Subject: Does BUFQ_GET/PUT need a lock?
To: None <tech-kern@netbsd.org>
From: Gordon Waidhofer <gww@traakan.com>
List: tech-kern
Date: 07/20/2004 21:54:58
Defined in sys/buf.h and kern/subr_disk.c, the
BUFQ_PUT() and BUFQ_GET() mechanisms manipulate
disk I/O request queues. A device driver's strategy()
routine uses BUFQ_PUT() to put a new request in
an advantageous place in the queue. The device
driver's start routine uses BUFQ_GET() to obtain the
next request to issue to the device.

The strategy() routine can be entered a variety
of ways. The most likely path is through VOP_STRATEGY().
The strategy() routine merges requests for
multiple partitions into one queue. The vnode
locks may provide locking for individual partitions
but not for the overall device. So I don't
see any way for the VOPs to provide exclusion.

I expected to find a spinlock on the bufq_state
structure, but did not.

So I think there is a race condition or I'm
missing something.

Multiple CPUs can enter strategy(), perhaps
with different partitions each, and try to
BUFQ_PUT(). There is no lock to keep things
sane. Similarly, the device start() routine
could conflict with threads running in strategy().

I have a pressing concern that multiple
threads be able to instigate disk I/O.
Any help appreciated.

Regards,
	-gww