diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2009-12-03 14:31:04 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2009-12-03 14:31:04 +0000 |
commit | 36248a1ec61b88fe6a01f270d58658df81e36f54 (patch) | |
tree | fd2889b64491998f8d021db1ae9099327f0a69f0 /sys/scsi/sd.c | |
parent | 5d60ca0fd0cb50ff9e57c9facd10a9f81565bb89 (diff) |
prevent a completion interrupt pulling io of the buf queue and shoving it
down to the disk while a process is doing the same thing. this will avoid
some relatively minor io reordering from occurring.
discovered by krw@ during his long dark trek through the code. requested
by marco@
Diffstat (limited to 'sys/scsi/sd.c')
-rw-r--r-- | sys/scsi/sd.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/sys/scsi/sd.c b/sys/scsi/sd.c index 08378cbcc33..87a0133f647 100644 --- a/sys/scsi/sd.c +++ b/sys/scsi/sd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sd.c,v 1.168 2009/12/03 06:09:30 dlg Exp $ */ +/* $OpenBSD: sd.c,v 1.169 2009/12/03 14:31:03 dlg Exp $ */ /* $NetBSD: sd.c,v 1.111 1997/04/02 02:29:41 mycroft Exp $ */ /*- @@ -171,6 +171,7 @@ sdattach(struct device *parent, struct device *self, void *aux) SC_DEBUG(sc_link, SDEV_DB2, ("sdattach:\n")); mtx_init(&sd->sc_buf_mtx, IPL_BIO); + mtx_init(&sd->sc_start_mtx, IPL_BIO); /* * Store information needed to contact our base driver @@ -691,6 +692,15 @@ sdstart(void *v) SC_DEBUG(sc_link, SDEV_DB2, ("sdstart\n")); + mtx_enter(&sc->sc_start_mtx); + if (ISSET(sc->flags, SDF_STARTING)) { + mtx_leave(&sc->sc_start_mtx); + return; + } + + SET(sc->flags, SDF_STARTING); + mtx_leave(&sc->sc_start_mtx); + CLR(sc->flags, SDF_WAITING); while (!ISSET(sc->flags, SDF_WAITING) && (bp = sd_buf_dequeue(sc)) != NULL) { @@ -710,7 +720,7 @@ sdstart(void *v) xs = scsi_xs_get(link, SCSI_NOSLEEP); if (xs == NULL) { sd_buf_requeue(sc, bp); - return; + break; } blkno = @@ -755,6 +765,10 @@ sdstart(void *v) scsi_xs_exec(xs); } + + mtx_enter(&sc->sc_start_mtx); + CLR(sc->flags, SDF_STARTING); + mtx_leave(&sc->sc_start_mtx); } void |