For most of the block drivers bio_endio runs in a context of its tasklet, so it is indeed atomic context. -Rajat On Fri, Nov 11, 2011 at 4:50 AM, Kai Meyer <kai@xxxxxxxxxx> wrote: > > > On 11/10/2011 04:00 PM, Jeff Haran wrote: >>> -----Original Message----- >>> From: kernelnewbies-bounces@xxxxxxxxxxxxxxxxx [mailto:kernelnewbies- >>> bounces@xxxxxxxxxxxxxxxxx] On Behalf Of Kai Meyer >>> Sent: Thursday, November 10, 2011 1:55 PM >>> To: kernelnewbies@xxxxxxxxxxxxxxxxx >>> Subject: Re: Spinlocks and interrupts >>> >>> Alright, to summarize, for my benefit mostly, >>> >>> I'm writing a block device driver, which has 2 entry points into my >> code >>> that will reach this critical section. It's either the make request >>> function for the block device, or the resulting bio->bi_end_io >> function. >>> I do some waiting with msleep() (for now) from the make request >> function >>> entry point, so I'm confident that entry point is not in an atomic >>> context. I also only end up requesting the critical section to call >>> kmalloc from this context, which is why I never ran into the >> scheduling >>> while atomic issue before. >>> >>> I'm fairly certain the critical section executes in thread context not >>> interrupt context from either entry point. >>> >>> I'm certain that the spinlock_t is only ever used in one function (a I >>> posted a simplified version of the critical section earlier). >>> >>> It seems that the critical section is often called in an atomic >> context. >>> The spin_lock function sounds like it will only cause a second call to >>> spin_lock to spin if it is called on a separate core. >>> >>> But, since I'm certain the critical section is never called from >>> interrupt context, only thread context, the fact that pre-emption is >>> disabled on the core should provide the protection I need with out >>> having to disable IRQs. Disabling IRQs would prevent an interrupt from >>> occurring while the lock is acquired. I would like to avoid disabling >>> interrupts if I don't need to. >>> >>> So it sounds like spin_lock/spin_unlock is the correct choice? >>> >>> In addition, I'd like to be more confident in my assumptions above. >> Can >>> I test for atomic context? For instance, I know that you can call >>> irqs_disabled(), is there a similar is_atomic() function I can call? I >>> would like to put a few calls in different places to learn what sort >> of >>> context I'm. >>> >>> -Kai Meyer >>> >>> On 11/10/2011 12:19 PM, Jeff Haran wrote: >>>>> -----Original Message----- >>>>> From: kernelnewbies- >>> bounces+jharan=bytemobile.com@xxxxxxxxxxxxxxxxx >>>>> [mailto:kernelnewbies- >>>>> bounces+jharan=bytemobile.com@xxxxxxxxxxxxxxxxx] On Behalf Of >>> Dave >>>>> Hylands >>>>> Sent: Thursday, November 10, 2011 11:07 AM >>>>> To: Kai Meyer >>>>> Cc: kernelnewbies@xxxxxxxxxxxxxxxxx >>>>> Subject: Re: Spinlocks and interrupts >>>>> >>>>> Hi Kai, >>>>> >>>>> On Thu, Nov 10, 2011 at 10:14 AM, Kai Meyer<kai@xxxxxxxxxx> wrote: >>>>>> I think I get it. I'm hitting the scheduling while atomic because >>>> I'm >>>>>> calling my function from a struct bio's endio function, which is >>>>>> probably running with a lock held somewhere else, and then my >> mutex >>>>>> sleeps, while the spin_lock functions do not sleep. >>>>> Actually, just holding a lock doesn't create an atomic context. >>>> I believe on kernels with kernel pre-emption enabled the act of >> taking >>>> the lock disables pre-emption. If it didn't work this way you could >> end >>>> up taking the lock in one process context and while the lock was >> held >>>> get pre-empted. Then another process tries to take the lock and you >> dead >>>> lock. >>>> >>>> Jeff Haran >>>> >> Kai, you might want to try bottom posting. It is the standard on these >> lists. It makes it easier for others to follow the thread. >> >> I know of no kernel call that you can make to test for current execution >> context. There are the in_irq(), in_interrupt() and in_softirq() macros >> in hardirq.h, but when I've looked at the code that implements them I've >> come to the conclusion that they sometimes will lie. in_softirq() >> returns non-zero if you are in a software IRQ. Fair enough. But based on >> my reading in the past it's looked to me like it will also return >> non-zero if you've disabled bottom halves from process context with say >> a call to spin_lock_bh(). >> >> It would be nice if there were some way of asking the kernel what >> context you are in, for debugging if for no other reason, but if it's >> there I haven't found it. >> >> I'd love to be proven wrong here, BTW. If others know better, please >> enlighten me. >> >> Jeff Haran >> >> >> >> >> _______________________________________________ >> Kernelnewbies mailing list >> Kernelnewbies@xxxxxxxxxxxxxxxxx >> http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies > > I try to remember to bottom post on message lists, but obviously I've > been negligent :) > > Perhaps I'll just add some calls to msleep() at various places to help > me identify when portions of my code are in an atomic context, just to > help me learn what's going on. > > -Kai Meyer > > _______________________________________________ > Kernelnewbies mailing list > Kernelnewbies@xxxxxxxxxxxxxxxxx > http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies > _______________________________________________ Kernelnewbies mailing list Kernelnewbies@xxxxxxxxxxxxxxxxx http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies