* interrupt context @ 2003-04-14 18:51 Jeremy Hall 2003-04-14 18:56 ` Robert Love 0 siblings, 1 reply; 13+ messages in thread From: Jeremy Hall @ 2003-04-14 18:51 UTC (permalink / raw) To: linux-mm Hi, On a UP machine, is it possible for two interrupts to occur at once? as in, can card a create an interrupt while card b is in interrupt context? what about an SMP machine operating in UP mode (nosmp) _J -- 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> ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: interrupt context 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 21:09 ` Jeremy Hall 0 siblings, 2 replies; 13+ messages in thread From: Robert Love @ 2003-04-14 18:56 UTC (permalink / raw) To: Jeremy Hall; +Cc: linux-mm On Mon, 2003-04-14 at 14:51, Jeremy Hall wrote: > On a UP machine, is it possible for two interrupts to occur at once? as > in, can card a create an interrupt while card b is in interrupt context? Yes. Normally, all interrupts are enabled (the interrupt system is on) but the _current_ interrupt line is masked out. Thus you will never get a recursive interrupt (A while processing A) but you may get A while processing B. Note if SA_INTERRUPT flag was given to request_irq() then the interrupt is a "fast" interrupt and runs with all interrupts disabled on the local processor. > what about an SMP machine operating in UP mode (nosmp) By nature of above, yes. If you need to ensure concurrency is protected in your interrupt handler, grab a lock and disable interrupts around the critical region. 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> ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: interrupt context 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 1 sibling, 1 reply; 13+ messages in thread From: Jeremy Hall @ 2003-04-14 19:32 UTC (permalink / raw) To: Robert Love; +Cc: Jeremy Hall, linux-mm In the new year, Robert Love wrote: > On Mon, 2003-04-14 at 14:51, Jeremy Hall wrote: > > If you need to ensure concurrency is protected in your interrupt > handler, grab a lock and disable interrupts around the critical region. > I am assuming you mean in some parent context. on alsa-devel, I wrote: Consider the following: Two RME9652's are running together and on different interrupts. The master, in interrupt context, acquires its runtime->lock and begins snd_pcm_update_hw_ptr_interrupt() At the same time, the second card, the slave, is behind, still in play mode, and wants to XRUN. To do that, it must stop and restart all the substreams connected to it. To do that, it must acquire the runtime lock of each, but the capture substream of the master is locked in another interrupt. solution: Is it acceptible if XRUN occurs in a pcm_multi environment to only restart substreams related to that physical card? or is it necessary to restart the whole device to maintain sample-sync? I'm thinking you'd need to restart all devices. Is this reasonable? as in, am I reading the code correctly? _J The ideal solution would be to put both rme cards on the same interrupt, but I haven't been able to figure out how to do that, unless it is as simple as setting interrupt_line with setpci, but when the pcm_multi device is set up, it should find a way to figure out which interrupt(s) are functioning as a single device and mask them together somehow. and this calling snd_pcm_period_elapsed from the interrupt handler but after clearing the interrupt (rme9652.c) i think is ultimately how this can occur. I'm thinking that even IF they were both on the same interrupt this could occur because the irq is cleared before snd_pcm_period_elapsed runs. _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> ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: interrupt context 2003-04-14 19:32 ` Jeremy Hall @ 2003-04-14 19:35 ` Robert Love 0 siblings, 0 replies; 13+ messages in thread From: Robert Love @ 2003-04-14 19:35 UTC (permalink / raw) To: Jeremy Hall; +Cc: linux-mm On Mon, 2003-04-14 at 15:32, Jeremy Hall wrote: > I am assuming you mean in some parent context. No, I mean in the interrupt handler. You can grab spin locks in interrupt handlers. You probably also want to disable interrupts locally. 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> ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: interrupt context 2003-04-14 18:56 ` Robert Love 2003-04-14 19:32 ` Jeremy Hall @ 2003-04-14 21:09 ` Jeremy Hall 2003-04-14 21:18 ` Robert Love 1 sibling, 1 reply; 13+ messages in thread From: Jeremy Hall @ 2003-04-14 21:09 UTC (permalink / raw) To: Robert Love; +Cc: Jeremy Hall, linux-mm In the new year, Robert Love wrote: > On Mon, 2003-04-14 at 14:51, Jeremy Hall wrote: > > Note if SA_INTERRUPT flag was given to request_irq() then the interrupt > is a "fast" interrupt and runs with all interrupts disabled on the local > processor. > with 2.5.67-mm2, it is SA_INTERRUPT|SA_SHIRQ and looks like it can call multiple interrupts at once. I am not sure what SA_SHIRQ does, but this does not address the case where one CPU holds an interrupt for one card and the other CPU holds the interrupt for the other card. I moved the line rme9652_write(rme9652, RME9652_irq_clear, 0); to after the snd_pcm_period_elapsed calls in the hopes that they would be run in interrupt context, but it did not make a difference. The backtrace looks a little different, but it's still the same crash. _J -- 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> ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: interrupt context 2003-04-14 21:09 ` Jeremy Hall @ 2003-04-14 21:18 ` Robert Love 2003-04-14 21:48 ` Jeremy Hall 0 siblings, 1 reply; 13+ messages in thread From: Robert Love @ 2003-04-14 21:18 UTC (permalink / raw) To: Jeremy Hall; +Cc: linux-mm On Mon, 2003-04-14 at 17:09, Jeremy Hall wrote: > with 2.5.67-mm2, it is SA_INTERRUPT|SA_SHIRQ and looks like it can call > multiple interrupts at once. I am not sure what SA_SHIRQ does, but this > does not address the case where one CPU holds an interrupt for one card > and the other CPU holds the interrupt for the other card. SA_SHIRQ means "this interrupt line can be shared" -- thus each handler on the line needs to be able to differentiate when it is called whether or not its device actually caused the interrupt. Note two processors can never run the _same_ handler for the same line. A given line (say IRQ 8) is masked out on all processors while its handler. Further, if SA_INTERRUPT is specified then all other interrupts are disabled, too, on the local processor. If you need to protect some data, grab a spin lock in your handler. > I moved the line > > rme9652_write(rme9652, RME9652_irq_clear, 0); > > to after the snd_pcm_period_elapsed calls in the hopes that they would be > run in interrupt context, but it did not make a difference. The backtrace > looks a little different, but it's still the same crash. I am afraid I don't understand nearly enough of the context of the problem to know what to suggest next. Keep hacking :) 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> ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: interrupt context 2003-04-14 21:18 ` Robert Love @ 2003-04-14 21:48 ` Jeremy Hall 2003-04-14 22:57 ` Robert Love 0 siblings, 1 reply; 13+ messages in thread From: Jeremy Hall @ 2003-04-14 21:48 UTC (permalink / raw) To: Robert Love; +Cc: Jeremy Hall, linux-mm In the new year, Robert Love wrote: > On Mon, 2003-04-14 at 17:09, Jeremy Hall wrote: > > > with 2.5.67-mm2, it is SA_INTERRUPT|SA_SHIRQ and looks like it can call > > multiple interrupts at once. I am not sure what SA_SHIRQ does, but this > > does not address the case where one CPU holds an interrupt for one card > > and the other CPU holds the interrupt for the other card. > > SA_SHIRQ means "this interrupt line can be shared" -- thus each handler > on the line needs to be able to differentiate when it is called whether > or not its device actually caused the interrupt. > oh, ok. > Note two processors can never run the _same_ handler for the same line. > A given line (say IRQ 8) is masked out on all processors while its > handler. > ok, but in this case, the same handler appears on two different lines, once for one RME card, once for the other. It is theoretically possible that one line could be handled by once CPU and the other by the other CPU. > Further, if SA_INTERRUPT is specified then all other interrupts are > disabled, too, on the local processor. > It would appear this may not be true, or my understanding of the code is not sound (more likely) it would also appear rme9652_read might not be able to differuntiate between being called for an RME card or another card. rme9652_read says return readl(rme9652->iobase+reg); oh yeah and it says if it can't read, it just returns. I guess it can tell the difference. > If you need to protect some data, grab a spin lock in your handler. > I'm still digging at this, so don't know yet how to answer this point. I'm thinking somehow we need to schedule the snd_pcm_period_elapsed, or force it to run in interrupt context. I thought I had done the latter by moving the snd_rme9652_write to the bottom of the function so that it wouldn't clear the interrupt condition until after it processed the data. but I guess I hadn't because it didn't make a difference. This is why I raise the question about whether other interrupts can be called. _J > > I moved the line > > > > rme9652_write(rme9652, RME9652_irq_clear, 0); > > > > to after the snd_pcm_period_elapsed calls in the hopes that they would be > > run in interrupt context, but it did not make a difference. The backtrace > > looks a little different, but it's still the same crash. > > I am afraid I don't understand nearly enough of the context of the > problem to know what to suggest next. > > Keep hacking :) > > 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> > -- 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> ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: interrupt context 2003-04-14 21:48 ` Jeremy Hall @ 2003-04-14 22:57 ` Robert Love 2003-04-15 3:44 ` Jeremy Hall 0 siblings, 1 reply; 13+ messages in thread From: Robert Love @ 2003-04-14 22:57 UTC (permalink / raw) To: Jeremy Hall; +Cc: linux-mm On Mon, 2003-04-14 at 17:48, Jeremy Hall wrote: > > Note two processors can never run the _same_ handler for the same line. > > A given line (say IRQ 8) is masked out on all processors while its > > handler. > > ok, but in this case, the same handler appears on two different lines, > once for one RME card, once for the other. It is theoretically possible > that one line could be handled by once CPU and the other by the other CPU. Yep. You must obtain a spin lock and disable local interrupts if there is any shared data here (and I am sure there is). > > Further, if SA_INTERRUPT is specified then all other interrupts are > > disabled, too, on the local processor. > > > It would appear this may not be true, or my understanding of the code is > not sound (more likely) it would also appear rme9652_read might not be > able to differuntiate between being called for an RME card or another > card. It is true :) See irq.c for your architecture. On x86, we have handle_IRQ_event(): if (!(action->flags & SA_INTERRUPT)) local_irq_enable(); It is called with interrupts disabled. Unless SA_INTERRUPT is set, though, they are enabled here. Note this is the _local_ processor only. > I'm still digging at this, so don't know yet how to answer this point. > I'm thinking somehow we need to schedule the snd_pcm_period_elapsed, or > force it to run in interrupt context. > > I thought I had done the latter by moving the snd_rme9652_write to the > bottom of the function so that it wouldn't clear the interrupt condition > until after it processed the data. > > but I guess I hadn't because it didn't make a difference. This is why I > raise the question about whether other interrupts can be called. Well, as I have said, they can still run on OTHER processors, as long as its a different interrupt line (same handler is irrelevant). So you can have these two handlers you speak of run at the same time. I think you are trying to prevent that, no? Well, you cannot... but you can protect the shared data or hardware with a lock. Grab a spin_lock in the handler prior to doing what you wish to protect. This will prevent that chunk of code from running simultaneously. Linus has a nice discussion on spin locks in Documentation/spinlocks.txt 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> ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: interrupt context 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 0 siblings, 2 replies; 13+ messages in thread From: Jeremy Hall @ 2003-04-15 3:44 UTC (permalink / raw) To: Robert Love; +Cc: Jeremy Hall, linux-mm In the new year, Robert Love wrote: > On Mon, 2003-04-14 at 17:48, Jeremy Hall wrote: > > > > Note two processors can never run the _same_ handler for the same line. > > > A given line (say IRQ 8) is masked out on all processors while its > > > handler. > > > > ok, but in this case, the same handler appears on two different lines, > > once for one RME card, once for the other. It is theoretically possible > > that one line could be handled by once CPU and the other by the other CPU. > > Yep. You must obtain a spin lock and disable local interrupts if there > is any shared data here (and I am sure there is). > 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. > > I'm still digging at this, so don't know yet how to answer this point. > > I'm thinking somehow we need to schedule the snd_pcm_period_elapsed, or > > force it to run in interrupt context. > > > > I thought I had done the latter by moving the snd_rme9652_write to the > > bottom of the function so that it wouldn't clear the interrupt condition > > until after it processed the data. > > > > but I guess I hadn't because it didn't make a difference. This is why I > > raise the question about whether other interrupts can be called. > > Well, as I have said, they can still run on OTHER processors, as long as > its a different interrupt line (same handler is irrelevant). > yes, I understand, but I had put nosmp and acpi=off in the boot line. There should have only been one processor, indeed I verified /proc/cpuinfo only showed one, although the kernel was compiled for SMP. > So you can have these two handlers you speak of run at the same time. I > think you are trying to prevent that, no? > I am trying to prevent one card from stopping while the other is reading. They can both read or write or whatever at the same time, but if state needs to be changed, everything needs to come to a stop so the state can change. > Well, you cannot... but you can protect the shared data or hardware with > a lock. Grab a spin_lock in the handler prior to doing what you wish to > protect. This will prevent that chunk of code from running > simultaneously. > yes I understand what you are saying. > Linus has a nice discussion on spin locks in Documentation/spinlocks.txt > yes sorry for the silly dialog. I'll post a backtrace so maybe it will be more clear. _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> ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: interrupt context 2003-04-15 3:44 ` Jeremy Hall @ 2003-04-15 4:14 ` Jeremy Hall 2003-04-15 21:40 ` Robert Love 1 sibling, 0 replies; 13+ messages in thread From: Jeremy Hall @ 2003-04-15 4:14 UTC (permalink / raw) To: Jeremy Hall; +Cc: Robert Love, Jeremy Hall, linux-mm In the new year, Jeremy Hall wrote: > In the new year, Robert Love wrote: > > On Mon, 2003-04-14 at 17:48, Jeremy Hall wrote: > > > yes sorry for the silly dialog. I'll post a backtrace so maybe it will be > more clear. > and btw I appreciate your help. :) Script started on Mon Apr 14 23:44:43 2003 Rainbow:/usr/src/linux-2.5.67 # gdb vmlinux GNU gdb 5.3 Copyright 2002 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i686-pc-linux-gnu"... gdb_interrupt (irq=4, dev_id=0x0, regs=0xdae4fc74) at arch/i386/lib/kgdb_serial.c:194 194 continue ; warning: shared library handler failed to enable breakpoint (gdb) bt #0 gdb_interrupt (irq=4, dev_id=0x0, regs=0xdae4fc74) at arch/i386/lib/kgdb_serial.c:194 #1 0xc010cd68 in handle_IRQ_event (irq=4, regs=0xdae4fc74, action=0xdffee640) at arch/i386/kernel/irq.c:214 #2 0xc010cfd1 in do_IRQ (regs= {ebx = -604748800, ecx = 32, edx = -604748632, esi = -604748632, edi = 10, ebp = -622527312, eax = -622534656, xds = 123, xes = 123, orig_eax = -252, eip = -1072561613, xcs = 96, eflags = 646, esp = -604748800, xss = -1049704384}) at arch/i386/kernel/irq.c:395 #3 0xc010b60c in common_interrupt () at net/8021q/vlan.c:130 #4 0xc033b857 in snd_pcm_period_elapsed (substream=0xc16ec840) at sound/core/pcm_lib.c:2014 #5 0xc0340fa8 in snd_rme9652_interrupt (irq=10, dev_id=0xc1679dc8, regs=0xdae4fd20) at sound/pci/rme9652/rme9652.c:1959 #6 0xc010cd68 in handle_IRQ_event (irq=10, regs=0xdae4fd20, action=0xc1700be0) at arch/i386/kernel/irq.c:214 #7 0xc010cfd1 in do_IRQ (regs= {ebx = -622534656, ecx = 1, edx = 578454, esi = -1049704384, edi = -604748800, ebp = -622527128, eax = -1049974272, xds = 123, xes = 123, orig_eax = -246, eip = -1070407894, xcs = 96, eflags = 514, esp = -622534656, xss = -1049704384}) at arch/i386/kernel/irq.c:395 #8 0xc010b60c in common_interrupt () at net/8021q/vlan.c:130 #9 0xc0332d81 in snd_pcm_stop (substream=0xc16ec9c0, state=4) at sound/core/pcm_native.c:712 #10 0xc0338030 in snd_pcm_update_hw_ptr_interrupt (substream=0xc16ec9c0) at sound/core/pcm_lib.c:179 #11 0xc033b88e in snd_pcm_period_elapsed (substream=0xc16ec9c0) at sound/core/pcm_lib.c:2016 #12 0xc0340fa8 in snd_rme9652_interrupt (irq=12, dev_id=0xc17171c8, regs=0xdae4fe2c) at sound/pci/rme9652/rme9652.c:1959 #13 0xc010cd68 in handle_IRQ_event (irq=12, regs=0xdae4fe2c, action=0xc1700340) at arch/i386/kernel/irq.c:214 #14 0xc010cfd1 in do_IRQ (regs= {ebx = 1064997, ecx = 433565696, edx = -1069105792, esi = -1053505848, edi = -640172440, ebp = -622526864, eax = 3688, xds = 123, xes = 123, orig_eax = -244, eip = -1072398266, xcs = 96, eflags = 582, esp = -613946388, xss = -602417088}) at arch/i386/kernel/irq.c:395 #15 0xc010b60c in common_interrupt () at net/8021q/vlan.c:130 #16 0xc01481b8 in do_no_page (mm=0xdc17d840, vma=0xd6070cc0, address=3204030464, write_access=1, page_table=0xd9d7be68, pmd=0xdb67ebec) at mm/memory.c:1332 #17 0xc014870c in handle_mm_fault (mm=0xdc17d840, vma=0xd6070cc0, address=3204030464, write_access=1) at mm/memory.c:1483 #18 0xc0146e55 in get_user_pages (tsk=0xdbde8cc0, mm=0xdc17d840, start=3204030464, len=102, write=1, force=0, pages=0x0, vmas=0x0) at mm/memory.c:718 #19 0xc01488b4 in make_pages_present (addr=3202351104, end=3204448256) at mm/memory.c:1580 #20 0xc0149f3c in do_mmap_pgoff (file=0x0, addr=3202351104, len=2097152, ---Type <return> to continue, or q <return> to quit--- prot=7, flags=34, pgoff=0) at mm/mmap.c:733 #21 0xc0111701 in old_mmap (arg=0x40c37e0c) at arch/i386/kernel/sys_i386.c:59 (gdb) up > _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> ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: interrupt context 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 2003-04-16 3:41 ` Jeremy Hall 1 sibling, 2 replies; 13+ messages in thread From: Robert Love @ 2003-04-15 21:40 UTC (permalink / raw) To: Jeremy Hall; +Cc: linux-mm 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? 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> ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: interrupt context 2003-04-15 21:40 ` Robert Love @ 2003-04-15 23:02 ` Jeremy Hall 2003-04-16 3:41 ` Jeremy Hall 1 sibling, 0 replies; 13+ messages in thread From: Jeremy Hall @ 2003-04-15 23:02 UTC (permalink / raw) To: Robert Love; +Cc: Jeremy Hall, linux-mm, paul [-- 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) { ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: interrupt context 2003-04-15 21:40 ` Robert Love 2003-04-15 23:02 ` Jeremy Hall @ 2003-04-16 3:41 ` Jeremy Hall 1 sibling, 0 replies; 13+ messages in thread From: Jeremy Hall @ 2003-04-16 3:41 UTC (permalink / raw) To: Robert Love; +Cc: Jeremy Hall, linux-mm With the tasklet version, I now have a different problem and don't fully understand how we got here. Both CPUs are in snd_pcm_stop, which is a macro. gdb has a hard time with this and can't reference some of the preprocessor code. snd_pcm_stop is running for the same card but on different CPUs. How'd that happen? I thought the tasklet wouldn't run ... oh but it only blocks itself from running on the local CPU twice nice Do I need to use spin_lock_irqsave or spin_lock to protect itself from running concurrently on different CPUs? _J 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? > > 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> ^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2003-04-16 3:41 UTC | newest] Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 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 2003-04-16 3:41 ` Jeremy Hall
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox