diff options
author | Bob Beck <beck@cvs.openbsd.org> | 2010-01-11 00:14:53 +0000 |
---|---|---|
committer | Bob Beck <beck@cvs.openbsd.org> | 2010-01-11 00:14:53 +0000 |
commit | b00143e86b80f1a913de6aba6443f4dd9965d3d1 (patch) | |
tree | 8f5146636d716dc43bdf136a7381150f4fc5a8f5 /sys/scsi | |
parent | b2480ddbed82117bd2bfb999763c61efa5292e31 (diff) |
Add mutex around work consuming loop in sdstart - this ensures that only
one thread will be grabbing xs's at a time and dequeuing work, but avoids
a race between notification there is work to do and exiting the loop
releasing the xs's.
Fixes problem noticed by claudio where usb disks would hang with the new
minty dlg midlayer.
ok krw@, dlg@, tested by claudio@
Diffstat (limited to 'sys/scsi')
-rw-r--r-- | sys/scsi/sd.c | 18 | ||||
-rw-r--r-- | sys/scsi/sdvar.h | 4 |
2 files changed, 19 insertions, 3 deletions
diff --git a/sys/scsi/sd.c b/sys/scsi/sd.c index f00ca42ab28..08a398c319c 100644 --- a/sys/scsi/sd.c +++ b/sys/scsi/sd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sd.c,v 1.176 2010/01/09 21:12:06 dlg Exp $ */ +/* $OpenBSD: sd.c,v 1.177 2010/01/11 00:14:52 beck Exp $ */ /* $NetBSD: sd.c,v 1.111 1997/04/02 02:29:41 mycroft Exp $ */ /*- @@ -693,6 +693,14 @@ sdstart(void *v) SC_DEBUG(link, SDEV_DB2, ("sdstart\n")); + mtx_enter(&sc->sc_start_mtx); + sc->sc_start_count++; + if (sc->sc_start_count > 1) { + mtx_leave(&sc->sc_start_mtx); + return; + } + mtx_leave(&sc->sc_start_mtx); +restart: CLR(sc->flags, SDF_WAITING); while (!ISSET(sc->flags, SDF_WAITING) && (bp = sd_buf_dequeue(sc)) != NULL) { @@ -759,6 +767,14 @@ sdstart(void *v) scsi_xs_exec(xs); } + mtx_enter(&sc->sc_start_mtx); + sc->sc_start_count--; + if (sc->sc_start_count != 0) { + sc->sc_start_count = 1; + mtx_leave(&sc->sc_start_mtx); + goto restart; + } + mtx_leave(&sc->sc_start_mtx); } void diff --git a/sys/scsi/sdvar.h b/sys/scsi/sdvar.h index ad44adf6b85..79517cfa32a 100644 --- a/sys/scsi/sdvar.h +++ b/sys/scsi/sdvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sdvar.h,v 1.26 2010/01/09 21:12:06 dlg Exp $ */ +/* $OpenBSD: sdvar.h,v 1.27 2010/01/11 00:14:52 beck Exp $ */ /* $NetBSD: sdvar.h,v 1.7 1998/08/17 00:49:03 mycroft Exp $ */ /*- @@ -72,10 +72,10 @@ struct sd_softc { } params; struct mutex sc_buf_mtx; struct mutex sc_start_mtx; + u_int sc_start_count; struct buf sc_buf_queue; void *sc_sdhook; /* our shutdown hook */ struct timeout sc_timeout; - }; #define SDGP_RESULT_OK 0 /* parameters obtained */ |