Subject: Re: splx() optimization [was Re: SMP re-eetrancy in "bottom half" drivers]
To: YAMAMOTO Takashi <yamt@mwd.biglobe.ne.jp>
From: Jonathan Stone <jonathan@dsg.stanford.edu>
List: tech-kern
Date: 06/05/2005 23:23:51
In message <1118010281.833339.657.nullmailer@yamt.dyndns.org>,
YAMAMOTO Takashi writes:

>> > we already have kernel_lock, which is exactly to emulate the existing
>> > synchronization semantics.
>> > why to bother to waste time to introduce and stabilize
>> > another stop-gap hack rather than doing real smp work?
>> 
>> But kernel_lock gives you _one_ level of mutual exclusion.  Unless I
>> misunderstand -- which is entirely possible -- what Jonathan is proposing
>> would give multiple levels.

Yes, it would. But that is only half of the reason.  Just as important
(perhaps more so) is that the kernel code we already have, (which is
non-SMP-safe) contines to work, as-is and unmodified, as we more
pieces of that kernel out from under the big kernel_lock.

The current, non-SMP, biglock semantics for SPLS _are_ implicitly
global, at least for spl levels where (by assumption) the calling code
already holds kernel_lock.  Therefore, to faithfully emulate the
current SPL calls in a kernel where the kernel_lock is not held on
entry to all interrupt handlers (or other kernel code which raises
spl), those spl*() calls *must* acquire some global lock.


>right.  of course, any stop-gap hack have some benefit. :-)
>
>my point is, given its complexity and overhead,
>it isn't worth to introduce this hack.

Huh?  The main point I see is to preserve the correctness of existing,
currently-correct code.  In my proposal, calls to splbio(), **in
existing code which is not yet re-written to use fine-grain
synchronization**, will acquire a lock associated with that spl level,
and will guarantee suitable synchronization -- even when other CPUs
are running inside the kernel.


Yamamoto-san, I've never had a clear picture of what you propose
instead for code which currently raises spl to (for example, lets say)
splbio(), if that affects only local-CPU interrupt priority.

Can you descrive how such code would work in your desired worldview
(i.e,. where spl()s do not acquire a lock, and affect only local-CPU
interrupt priority), when existing, not-yet-SMP-ified code calls
splbio() or spltty()?  How does that guarantee synchronization against
another CPU calling splbio()?  Say in the case where some disk drivers
have been made SMP-safe, but others haven't?
Or analagously for spltty() vs spltty()?

Sure, we could explicitly add calls to kernel_lock() _everywhere_ we
currently use SPLs, and that might be technically correct; but (to me
at least) that is just not feasible, given the developer resources we
have.  Much simpler to pay the cost of implicit locking at each spl
level.  But the implicit locks go away at the same time as each driver
or subsystem is reworked to be SMP-safe, with explicit fine-grained
synchroniation, and the sp*() calls are removed.

Yamamoto-san, I don't get it, sincerely I do not.  Why do you prefer
having to add explici kernel_lock() calls to all not-yet-SMP-ified
code, over the alternative --- where spl*() calls in current,
not-yet-SMP-ifed code continue to "just work "?  Is there something
I'm missing?

Or, to put that another way: given where NetBSD is today, how would
you propose to get from the current state, to a kernel with
fine-grained SMP synchronization?