tech-kern archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: Locking in disk(9) api
Hi,
On Dec,Tuesday 29 2009, at 1:49 AM, matthew green wrote:
>
> Yesterday tron@ submitted PR kern/42532 it's about panic which
> happen on device-mapper devices during concurrent access to them.
> After some investigation and help from others I have found that
> problem is that disk_busy and disk_unbusy requires users to manage
> locking for them. This problem wasn't found yet mostly because we
> don't have many D_MPSAFE enabled disk drivers and because dm is
> very specific in locking.
>
> the problem wasn't found in existing D_MPSAFE drivers because they
> hold a mutex around these calls, and the rest of the drivers hold
> the kernel lock. the fss(4) driver is also "very specific in
> locking."
I looked at fss driver and I think that it is working by luck only [1].
disk_unbusy iw for example called without any lock held. In [2]
disk_busy/disk_unbusy is called without any lock held, too.
[1] http://nxr.netbsd.org/xref/src/sys/dev/fss.c#1221
[2] http://nxr.netbsd.org/xref/src/sys/dev/fss.c#1059
>
> After some discussion I think that disk(9) api should be changed
> to manage locking by itself and to not require explicit locking
> from users. There are some options which can be used in this case,]
>
> 1) Use diskp->dk_openlock to lock access to
> iostat_busy/iostat_unbusy/iostat_isbusy
> 2) Use atomic operations in iostat_busy/iostat_unbusy/iostat_isbusy
> to manage io_stat reference counter
> 3) Add mutex to struct io_stat and use it to guard io_stat entries
> from concurrent manipulation. There are 4 functions which will
> need to acquire this lock
> iostat_busy/iostat_unbusy/iostat_isbusy/iostat_seek
> and iostat_free
>
>
> you forgot to list (0) - leave things as they are, ie, continue to
> require callers to manage locking. (also, update disk(9) to meantion
> an IPL_VM mutex instead of being at splbio().)
>
>
> it isn't clear to me that making every one pay the penalty of taking
> an additional lock twice for each IO is a good one to allow dm(4) to
> avoid managing locking itself.
>
> currently most of the disk drivers are not marked D_MPSAFE and thus
> they're implicitly serialised. ccd and fss both are marked D_MPSAFE
> and use internal locking logic to (a) ensure that disk_*busy() are
> called safely and (b) other internal logic happens safely.
For not D_MPSAFE locking and mutex should be a fast operation no ?
>
> since (b) is really required for disk devices anyway (and indeed,
> dm has other locks it manages internally), i don't see that making
> everyone pay the dual penalty (lock/unlock) just to avoid having
> dm(4) perform this locking itself is actually a benefit.
Because e.g. for dm there is no lock which I can hold for it. In my patch I'm
using dmv->diskp->dk_openlock which is hack I think, but it will work.
>
> after thinking about this during the afternoon, i'm more convinced
> that the current method is OK. dm(4) just needs a little fix, and
> i'm aware that adam has already sent a test patch for tron.
If you are ok with my patch attached below I will commit it .
- /* FIXME: have to be called with IPL_BIO*/
+ /* FIXME: There is a problem with disk(9) api because disk_busy and
+ disk_unbusy are not protected against concurrent usage and needs
+ explicit locking from caller.*/
+ mutex_enter(&dmv->diskp->dk_openlock);
disk_busy(dmv->diskp);
+ mutex_exit(&dmv->diskp->dk_openlock);
/* Select active table */
tbl = dm_table_get_entry(&dmv->table_head, DM_TABLE_ACTIVE);
@@ -459,8 +565,10 @@ dmstrategy(struct buf *bp)
if (issued_len < buf_len)
nestiobuf_done(bp, buf_len - issued_len, EINVAL);
- /* FIXME have to be called with SPL_BIO*/
+ /* FIXME disk_unbusy need to manage locking by itself. */
+ mutex_enter(&dmv->diskp->dk_openlock);
disk_unbusy(dmv->diskp, buf_len, bp != NULL ? bp->b_flags & B_READ : 0);
+ mutex_exit(&dmv->diskp->dk_openlock);
Regards
Adam.
Home |
Main Index |
Thread Index |
Old Index