tech-misc archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: Questions of lock usage in NetBSD kernel code
> Date: Sat, 24 Jun 2017 09:59:43 +0800
> From: Jia-Ju Bai <baijiaju1990%163.com@localhost>
>
> I am a freshman in developing NetBSD drivers, and I have a question in
> lock usage in NetBSD kernel code.
Cool!
> I find three kinds of locks which are often used in OpenBSD drivers,
^^^^^^^
I assume you mean NetBSD here! I'm afraid I'm not familiar enough
with OpenBSD to answer any analogous questions over there.
> namely "adaptive mutex lock", "spin mutex lock" and "rw lock".
> I want to know which locks can be held when the current thread can sleep.
>
> I have read NetBSD man pages:
> http://netbsd.gw.com/cgi-bin/man-cgi?mutex+9+NetBSD-current
> http://netbsd.gw.com/cgi-bin/man-cgi?rwlock+9+NetBSD-current
>
> I find two points:
> (1) The "adaptive mutex lock" *can* be used in this situation.
> (2) The "spin mutex lock" *can not* be used in this situation.
It is technically possible to sleep while holding an adaptive lock,
but the duration of sleep must be bounded -- you can't wait for
external I/O, and any other processes that are trying to acquire the
same adaptive lock are blocked uninterruptibly until you release it.
Sleeping with a spin lock held is absolutely prohibited and does not
work.
> But I still have three questions:
> (1) Are my points right?
> (2) What about "rw lock"?
> (3) What about other kinds of locks if they exist?
It is also technically possible to sleep while holding an rwlock, and
file systems do so even when waiting for I/O, but this is an abuse of
rwlocks because they're not interruptible and we should clean it up
one of these days. In general, if something might ever wait for I/O
before returning to userland, it should be interruptible.
There are other kinds of synchronization devices with related rules:
- Blocking interrupts (splnet, &c.): Sleeping while interrupts are
blocked works, but it reenables interrupts. Most new code doesn't
block interrupts directly -- instead uses mutex(9) or pserialize(9)
or other higher-level constructs that use it as a primitive.
- Disabling preemption (kpreempt_disable): Currently the kernel
doesn't crash if you sleep while preemption is disabled, but we may
change that because doing so is very error-prone. Also usually
limited to the internals of higher-level constructs.
- Passive serialization (pserialize): Read sections run with
interrupts blocked, and must not sleep.
- Passive references (psref): Users may sleep, but must be bound to a
CPU.
- CPU-local reference counts (localcount): Readers may sleep and
migrate across CPUs.
Home |
Main Index |
Thread Index |
Old Index