Re: Questions of lock usage in NetBSD kernel code
Jia-Ju Bai <[email protected]> Mon, 26 Jun 2017 09:54:16 +0800
| Newsgroups | gmane.os.netbsd.devel.kernel,gmane.os.netbsd.devel.general,gmane.os.netbsd.devel.smp |
|---|---|
| Message-ID | <[email protected]> |
Thanks for you reply and detailed answers :) On 06/26/2017 02:34 AM, Taylor R Campbell wrote: >> Date: Sat, 24 Jun 2017 09:59:43 +0800 >> From: Jia-Ju Bai<[email protected]> >> >> 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. Sorry for my mistake *_*, I mean NetBSD here. >> 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. I am happy to see that my under standing is right. >> 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. Your introduction of synchronization primitives and rules is very detailed, and it is very helpful to me, thanks a lot :) Thanks, Jia-Ju Bai