Re: Understanding locking for buf

From: Konstantin Belousov <kostikbel_at_gmail.com>
Date: Fri, 24 Feb 2023 20:41:48 UTC
On Fri, Feb 24, 2023 at 03:00:57PM +0100, Alexander Lochmann wrote:
> Hi Konstantin!
> 
> I'm sorry. I'm still struggling to understand locking of struct buf.
> As far as I know, a struct buf is (mostly) protected by b_lock.
> You already explained the concept of LK_KERNPROC.
> 
> I, however, have an instance of struct buf. That particular one is mostly
> accessed from just one context (aka thread) -- assuming synchronous IO.
> The other, unprotected accesses come from just one other context. Those
> accesses originate from 'g_vfs_done' [1].
> Why don't you release b_lock when buf goes further down the io stack, and
> acquire it again in g_vfs_done?
> This way the context of g_vfs_done would own the b_lock.
Unlocking the buffer means that other thread might take a lock.
This gives the new owner a permission to modify the buffer state and
data, causing the io operation in flight to corrupt data.  Or the buffer
might be reclaimed with brelse(), corrupting the kernel state.

> 
> Viewing it from a different angle: Are accesses in g_vfs_done safe because
> the buf instance is already locked from a global perspective?
> Hence, other code paths would block on BUF_LOCK().
geom completion code is the only code that allowed to touch the buffer
after the ownership was relinguished.

I believe I already tell that to you: consider the buffer lock after
LK_KERNPROC as a semaphore and not lock.