Linux Kernel Architecture

(Jacob Rumans) #1

Chapter 5: Locking and Interprocess Communication



  1. On no account should spinlocks be acquired for alonger period because all processors wait-
    ing for lock release are no longer available for other productive tasks (the situation with
    semaphores is different, as you will see shortly).


Code that is protected by spinlocksmustnotgotosleep.Thisruleisnotsosimple
to obey as it seems: It is not complicated to avoid going to sleep actively, but it must
also be ensured that none of the functions that are called inside a spinlocked region
can go to sleep! One particular example is thekmallocfunction: Usually the
requested memory will be returned straight away, but when the kernel is short on
memory, the functioncango to sleep, as discussed in Chapter 3. Code that makes
the mistake of allocating memory inside a spinlocked region will thus work
perfectly fine most of the time, but sometimes cause a failure. Naturally, such
problems areveryhard to reproduce and debug. Therefore, you should pay great
attention to which functions you call inside a spinlocked region, and make sure that
they cannot go to sleep in any circumstance.

On uniprocessor systems, spinlocks are defined as empty operations because critical sections cannot be
entered by several CPUs at the same time. However, this doesnotapply if kernel preemption is enabled.
If the kernel is interrupted in a critical region and this region is then entered by another process, this has
exactly the same effect as if the region were actuallybeing executed by two processors on SMP systems.
This is prevented by a simple trick — kernel preemption is disabled when the kernel is in a critical
region protected by a spinlock. When a uniprocessor kernel is compiled with enabled kernel preemption,
spin_lockis (basically) equivalent topreempt_disableandspin_unlocktopreempt_enable.

Spinlocks cannot be acquired more than once from the current holder! This is
especially important when functions thatcall other functions that each operate with
the same lock. If a lock has already been acquired and a function is called that tries
to again acquire it although the current code path is already holding the lock, a
deadlock will occur — the processor will wait for itself to release the lock, and this
mighttakeawhile...

Finally, notice that the kernel itself also provides some notes on how to use spinlocks in
Documentation/spinlocks.txt.

5.2.3 Semaphores


Semaphores that are used in the kernel are defined by the structure below. Userspace semaphores are
implemented differently, as described in Section 5.3.2.

<asm-arch/semaphore.h>
struct semaphore {
atomic_t count;
int sleepers;
wait_queue_head_t wait;
};
Free download pdf