Subject: Re: port bio(4) and bioctl(8) from openbsd ?
To: Manuel Bouyer <bouyer@antioche.eu.org>
From: Bill Stouder-Studenmund <wrstuden@netbsd.org>
List: tech-kern
Date: 04/21/2007 23:17:37
--/9DWx/yDrRhgMJTb
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

On Sat, Apr 21, 2007 at 03:48:08PM +0200, Manuel Bouyer wrote:
> Here's my latest patch about this.
> I've an issue with lock usage in bio(4):
> there is a bio_lock, which is a kmutex_t to protect the internal structur=
es
> of bio(4). A disk driver (for example mfi(4)) will also have its own
> lock to protect its structure; and will probably call bio_register()
> and bio_unregister() with this lock held.
> The callback from bio(4) to mfi(4) shall be called with bio_lock held, to
> avoid having the entry removed from under its feets (it's not the
> case right now, but as nothing calls bio_unregister() for now, it's
> safe).
> Now we could have this deadlock (theorically; because mfi doesn't have
> a mfi_detach):
> mfi_detach() takes the mfi mutex, and calls bio_unregister() which takes
>   bio_lock.
> bioioctl() takes bio_lock, and call backs in mfi(4) which will want to
>   take the mfi mutex.
>=20
> I'm not a multithread expert programmer. How is such case handled usually=
 ?

There are lots of ways to do this. One is reference counting. Another is=20
some sort of in-use flag. The idea is to have a second thing, other than=20
the lock, that indicates that it's in use. So once you do whatever, you=20
can be sure that the structure won't get wiped out from underneath you.

One way to do things would be to set a flag when the callout gets started
(before it is enqueued). Then clear the flag when the callout is done
running and has the mutex locked. If someone (the destroyer) wants to
delete the device (or whatever it is), if the "callout hasn't finished"
flag is set (remember to have the mutex locked when looking), set another
flag that says "tell me when you're done" & sleep waiting for the callout
to finish. Likewise, when the callout is clearing its "I'm running" flag,
it does something else to wake up the destroyer.

Reference counting is similar except it needs les corrdination. But it=20
does need you to be able to free memory/do final cleanup whenever you=20
release a reference. That might not be true in an interrupt handler.

Take care,

Bill

--/9DWx/yDrRhgMJTb
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.3 (NetBSD)

iD8DBQFGKv4BWz+3JHUci9cRArZfAJ9ilv/swJ0nS/MPnMYCJ+IdXXYc5QCfXVNR
A/179OOXlAs2qwWecE/kxUY=
=D5bc
-----END PGP SIGNATURE-----

--/9DWx/yDrRhgMJTb--