From: Jeremy Hall <jhall@maoz.com>
To: Robert Love <rml@tech9.net>
Cc: Jeremy Hall <jhall@maoz.com>,
linux-mm@kvack.org, paul@linuxaudiosystems.com
Subject: Re: interrupt context
Date: Tue, 15 Apr 2003 19:02:38 -0400 (EDT) [thread overview]
Message-ID: <200304152302.h3FN2ck4027380@sith.maoz.com> (raw)
In-Reply-To: <1050442843.3664.165.camel@localhost> from Robert Love at "Apr 15, 2003 05:40:44 pm"
[-- Attachment #1: Type: text/plain, Size: 2457 bytes --]
In the new year, Robert Love wrote:
> On Mon, 2003-04-14 at 23:44, Jeremy Hall wrote:
>
> > My quandery is where to put the lock so that both cards will use it. I
> > need a layer that is visible to both and don't fully understand the alsa
> > architecture enough to know where to put it.
>
> OK, I understand you now. :)
>
> What is the relationship between the two things that are conflicting?
>
Two copies of snd_pcm_period_elapsed were running concurrently, one for
one rme9652, one for the other. Both are linked together as a single
pcm_multi alsa device that an application is using. Because both cards
are on different interrupts, they can both run at the same time (the
rme9652 interrupt handler calls snd_pcm_period_elapsed)
Somehow the second handler got called while the first was running, and the
first had acquired a pcm spinlock. Because the first had been suspended
to run the second, deadlock occurred because the lock was never released.
There must be a common locking mechanism within the context of the
interrupt handler so that two interrupt handlers running the same code
don't deadlock. The dependency occurs from within the pcm_multi layer,
and that is where the "right" solution should be.
So to test, I wrote into the init routines, in the card discovery
mechanism, a common lock, I called it dev_lock, and made it a requirement
for running this function.
This was ok, except it meant that both devices can't run at the same time.
I wrote it up as a tasklet, which may or may not be the right solution
either, but at least now it won't deadlock and maybe both will run at the
same time.
I have attached both versions, and due to the way I applied it, you have
to apply the irq diffs, then the tasklet diffs to get the current code.
I'm not brave enough to say this should go in the alsa repository, but the
tasklet version has not yet deadlocked and I have seen several XRUNs going
by. I cannot guarantee I have seen the special-case condition, but
normally sooner or later deadlock occurs and it hasn't, running at LL
settings for 00:10:09:32, which I consider a win. Previously I'd see
deadlock within the first couple minutes.
_J
> Robert Love
>
> --
> To unsubscribe, send a message with 'unsubscribe linux-mm' in
> the body to majordomo@kvack.org. For more info on Linux MM,
> see: http://www.linux-mm.org/ .
> Don't email: <a href=mailto:"aart@kvack.org"> aart@kvack.org </a>
>
[-- Attachment #2: irq-diffs --]
[-- Type: text/plain, Size: 1477 bytes --]
--- rme9652.c Tue Apr 15 09:40:41 2003
+++ rme9652.c.jhall Tue Apr 15 09:37:15 2003
@@ -214,6 +214,7 @@
int dev;
spinlock_t lock;
+ spinlock_t *dev_lock;
int irq;
unsigned long port;
struct resource *res_port;
@@ -1950,13 +1951,13 @@
void snd_rme9652_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
rme9652_t *rme9652 = (rme9652_t *) dev_id;
+ unsigned long flags;
if (!(rme9652_read(rme9652, RME9652_status_register) & RME9652_IRQ)) {
return;
}
- rme9652_write(rme9652, RME9652_irq_clear, 0);
-
+ spin_lock_irqsave(rme9652->dev_lock, flags);
if (rme9652->capture_substream) {
snd_pcm_period_elapsed(rme9652->pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream);
}
@@ -1964,6 +1965,8 @@
if (rme9652->playback_substream) {
snd_pcm_period_elapsed(rme9652->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream);
}
+ spin_unlock_irqrestore(rme9652->dev_lock, flags);
+ rme9652_write(rme9652, RME9652_irq_clear, 0);
}
static snd_pcm_uframes_t snd_rme9652_hw_pointer(snd_pcm_substream_t *substream)
@@ -2674,6 +2677,7 @@
{
static int dev;
rme9652_t *rme9652;
+ static spinlock_t dev_lock;
snd_card_t *card;
int err;
@@ -2693,6 +2697,9 @@
rme9652 = (rme9652_t *) card->private_data;
card->private_free = snd_rme9652_card_free;
rme9652->dev = dev;
+ if (!dev)
+ spin_lock_init(&dev_lock);
+ rme9652->dev_lock = &dev_lock;
rme9652->pci = pci;
if ((err = snd_rme9652_create(card, rme9652, precise_ptr[dev])) < 0) {
[-- Attachment #3: tasklet-diffs --]
[-- Type: text/plain, Size: 2228 bytes --]
--- rme9652.c.jhall Tue Apr 15 09:37:15 2003
+++ rme9652.c Tue Apr 15 18:25:48 2003
@@ -214,7 +214,7 @@
int dev;
spinlock_t lock;
- spinlock_t *dev_lock;
+ struct tasklet_struct interrupt_tasklet;
int irq;
unsigned long port;
struct resource *res_port;
@@ -326,6 +326,8 @@
MODULE_DEVICE_TABLE(pci, snd_rme9652_ids);
+void rme9652_interrupt_tasklet(unsigned long arg);
+
static inline void rme9652_write(rme9652_t *rme9652, int reg, int val)
{
writel(val, rme9652->iobase + reg);
@@ -1951,13 +1953,20 @@
void snd_rme9652_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
rme9652_t *rme9652 = (rme9652_t *) dev_id;
- unsigned long flags;
if (!(rme9652_read(rme9652, RME9652_status_register) & RME9652_IRQ)) {
return;
}
- spin_lock_irqsave(rme9652->dev_lock, flags);
+ tasklet_hi_schedule(&rme9652->interrupt_tasklet);
+ rme9652_write(rme9652, RME9652_irq_clear, 0);
+}
+
+void
+rme9652_interrupt_tasklet(unsigned long arg)
+{
+ rme9652_t *rme9652 = (rme9652_t*)arg;
+
if (rme9652->capture_substream) {
snd_pcm_period_elapsed(rme9652->pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream);
}
@@ -1965,8 +1974,6 @@
if (rme9652->playback_substream) {
snd_pcm_period_elapsed(rme9652->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream);
}
- spin_unlock_irqrestore(rme9652->dev_lock, flags);
- rme9652_write(rme9652, RME9652_irq_clear, 0);
}
static snd_pcm_uframes_t snd_rme9652_hw_pointer(snd_pcm_substream_t *substream)
@@ -2560,6 +2567,7 @@
return err;
spin_lock_init(&rme9652->lock);
+ tasklet_init(&rme9652->interrupt_tasklet, rme9652_interrupt_tasklet, (unsigned long) rme9652);
rme9652->port = pci_resource_start(pci, 0);
if ((rme9652->res_port = request_mem_region(rme9652->port, RME9652_IO_EXTENT, "rme9652")) == NULL) {
@@ -2677,7 +2685,6 @@
{
static int dev;
rme9652_t *rme9652;
- static spinlock_t dev_lock;
snd_card_t *card;
int err;
@@ -2697,9 +2704,6 @@
rme9652 = (rme9652_t *) card->private_data;
card->private_free = snd_rme9652_card_free;
rme9652->dev = dev;
- if (!dev)
- spin_lock_init(&dev_lock);
- rme9652->dev_lock = &dev_lock;
rme9652->pci = pci;
if ((err = snd_rme9652_create(card, rme9652, precise_ptr[dev])) < 0) {
next prev parent reply other threads:[~2003-04-15 23:02 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2003-04-14 18:51 interrupt context Jeremy Hall
2003-04-14 18:56 ` Robert Love
2003-04-14 19:32 ` Jeremy Hall
2003-04-14 19:35 ` Robert Love
2003-04-14 21:09 ` Jeremy Hall
2003-04-14 21:18 ` Robert Love
2003-04-14 21:48 ` Jeremy Hall
2003-04-14 22:57 ` Robert Love
2003-04-15 3:44 ` Jeremy Hall
2003-04-15 4:14 ` Jeremy Hall
2003-04-15 21:40 ` Robert Love
2003-04-15 23:02 ` Jeremy Hall [this message]
2003-04-16 3:41 ` Jeremy Hall
2008-03-23 21:44 Interrupt context Codrin Alexandru Grajdeanu
2008-03-24 21:00 ` Christopher Li
2008-03-25 1:34 ` Octavian Purdila
2008-03-25 2:57 ` Christopher Li
2008-03-26 12:43 ` Octavian Purdila
2008-03-26 21:53 ` Christopher Li
[not found] <CA+bLfK5FPqFvU2xy7xKdV4LkAvmY6GAPFrB-4UBzn-cOunQ6Xg@mail.gmail.com>
2012-10-05 8:51 ` interrupt context Iain Fraser
2012-10-05 9:32 ` Borislav Petkov
2012-10-05 10:20 ` Iain Fraser
2012-10-05 10:34 ` Borislav Petkov
2012-10-05 13:27 ` Theodore Ts'o
2012-10-05 14:03 ` Iain Fraser
2012-10-05 18:05 ` anish kumar
2012-10-05 18:15 ` Iain Fraser
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200304152302.h3FN2ck4027380@sith.maoz.com \
--to=jhall@maoz.com \
--cc=linux-mm@kvack.org \
--cc=paul@linuxaudiosystems.com \
--cc=rml@tech9.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.