I've always been taught that sleeping while holding a spinlock in kernel code is a no-no. The reason for this is the following scenario:
- Thread A acquires the lock, does some work, and calls a kernel function that goes to sleep, releasing the CPU.
- Thread B now runs, which attempts to acquire the lock, but can't since its held by Thread A.
- This is a deadlock. Thread A can't get woken up since Thread B is constantly spinning and Thread B can't make any progress since it can't get the lock.
I am maintaining a driver which uses lots of locks and inside some of the locked sections are obvious things like memory allocations, copy_to_user()
, etc.
However, I am not entirely convinced that I have a bug on my hands. Using the above scenario, Thread A is user context (namely inside the implementation of read()
) while Thread B is the interrupt context (inside the ISR). The lock is locked via spin_lock_irqsave()
. As a result, Thread B cannot run while Thread A holds the lock, making the deadlock not possible.
I have also considered the following:
- Thread A = interrupt context. Here Thread A cannot sleep (and doesn't) so we never get into the deadlock condition.
- Thread A and B are both user context (i.e., concurrent calls to
read()
). This cannot happen due to other mechanisms in place.
Is there anything that I am missing? In what I described above, is there any real danger related to sleeping while holding the lock?