Why can not processes switch in atomic context?
Javier Martinez Canillas
martinez.javier at gmail.com
Wed Jul 4 04:21:24 EDT 2012
On Tue, Jul 3, 2012 at 4:24 PM, Parmenides <mobile.parmenides at gmail.com> wrote:
> Hi,
>
> It is said that kernel can not be preempted in interrupt context
> and when it is in a critical section protected by a spin lock.
>
> 1. For the spinlock case, it is easy to get if preemption is allowed
> in critical section, the purpose of protection provided by spinlock
> can not be achieved readily.
>
A process cannot be preempted nor sleep while holding a spinlock due
spinlocks behavior. If a process grabs a spinlock and goes to sleep
before releasing it. A second process (or an interrupt handler) that
to grab the spinlock will busy wait. On an uniprocessor machine the
second process will lock the CPU not allowing the first process to
wake up and release the spinlock so the second process can continue,
it is basically a deadlock.
This happens since grabbing an spinlocks also disables interrupts and
this is required to synchronize threads with interrupt handlers.
> 2. For the interrupt context case, I think when processing interrupt,
> kernel can be preempted in principle. But, this really increases the
> interrupt processing time which further cause longer response time and
> data missing in device. Except that, is there any other reasons?
>
The principal reason is quite simple, processes have an associated
task_struct and get executed when the scheduler chose to run it but
interrupt handlers are executed due an event (an interrupt happened on
the registered IRQ line).
So if you preempt an interrupt handler and schedule a process instead,
how could you execute the interrupt handler again? they don't have an
associated task_struct since they are not user-space process
> 3. Kernel is responsible for prohibiiting passive process switches,
> namely preemption, in the above cases. But, It seems that it does not
> take care of active process swtiches, namely yield. For example, some
> code in a critical section protected by a spinlock can invoke
> schedule() to switch process passively. Is this the case?
>
Right, the kernel just avoid process switching by disabling preemption
but you could still call schedule() or do a function call that sleeps
like allocating big chunks of memory with GFP_KERNEL flag instead of
GFP_ATOMIC, this is indeed a bug in the same way that is a bug
dereferencing a NULL pointer.
On the kernel hacking section of the Kbuild configuration you can find
many kconfig options to enable different debug facilities that helps
you detect these scenarios and avoid deadlock.
Hope it helps,
Javier
More information about the Kernelnewbies
mailing list