5.x locking plan
Matthew Dillon
dillon at apollo.backplane.com
Thu Mar 27 12:21:37 PST 2003
:My curiousity has overcome my fear of the bikeshed so I'll ask the
:question that has been bugging me for a while. Why haven't we gone
:through the tree and created a lock for each spl and then converted every
:spl call into the appropriate mtx_lock call? At that point, we can mark
:large sections of the tree giant-free and then make the locking data-based
:(instead of code-based) one section at a time. This is the approach
:Solaris took.
:
:-Nate
The problem is that SPLs are per-thread masks, and different sets of
bits can be added or removed from the master mask in any order and at
any time. There is no direct translation to a mutex (which cannot
be obtained in random order, is not per-thread, and may result in
preemption or a context switch).
Most of the code locked under Giant assumes the single-threading of
kernel threads regardless of the SPL. This 'inherent' single threading
is one the reasons why the original code was so efficient.
Since preemption can occur now under many new circumstances, including
when 'normal' (non-spin) mutexes are used to replace prior uses of SPLs
(which could not cause thread level preemption)... well, it basically
means there is no easy way to remove Giant short of going through every
bit of code and fixing it one subsystem at a time.
Giant itself is a special case. It is not a normal mutex. Instead, the
kernel very carefully saves and restores the state of Giant on a
per-thread basis so programs don't 'need to know' whether Giant is being
held or not and so Giant can be held in combination with another mutex
without violating the basic 'only one mutex can be held when going to
sleep' rule.
-Matt
Matthew Dillon
<dillon at backplane.com>
More information about the freebsd-arch
mailing list