Module Name: src
Committed By: mlelstv
Date: Thu Dec 22 13:42:15 UTC 2016
Modified Files:
src/sys/dev: dksubr.c dkvar.h
src/sys/sys: param.h
Log Message:
Fix race condition in dksubr, where a dk_start from another thread
or interrupt was ignored while the queue was processed.
Bump kernel revision for changed dk_softc.
To generate a diff of this commit:
cvs rdiff -u -r1.93 -r1.94 src/sys/dev/dksubr.c
cvs rdiff -u -r1.27 -r1.28 src/sys/dev/dkvar.h
cvs rdiff -u -r1.518 -r1.519 src/sys/sys/param.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/dev/dksubr.c
diff -u src/sys/dev/dksubr.c:1.93 src/sys/dev/dksubr.c:1.94
--- src/sys/dev/dksubr.c:1.93 Thu Dec 8 12:22:56 2016
+++ src/sys/dev/dksubr.c Thu Dec 22 13:42:14 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: dksubr.c,v 1.93 2016/12/08 12:22:56 mlelstv Exp $ */
+/* $NetBSD: dksubr.c,v 1.94 2016/12/22 13:42:14 mlelstv Exp $ */
/*-
* Copyright (c) 1996, 1997, 1998, 1999, 2002, 2008 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: dksubr.c,v 1.93 2016/12/08 12:22:56 mlelstv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: dksubr.c,v 1.94 2016/12/22 13:42:14 mlelstv Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -378,9 +378,16 @@ dk_start(struct dk_softc *dksc, struct b
if (bp != NULL)
bufq_put(dksc->sc_bufq, bp);
- if (dksc->sc_busy)
+ /*
+ * If another thread is running the queue, increment
+ * busy counter to 2 so that the queue is retried,
+ * because the driver may now accept additional
+ * requests.
+ */
+ if (dksc->sc_busy < 2)
+ dksc->sc_busy++;
+ if (dksc->sc_busy > 1)
goto done;
- dksc->sc_busy = true;
/*
* Peeking at the buffer queue and committing the operation
@@ -393,34 +400,37 @@ dk_start(struct dk_softc *dksc, struct b
* This keeps order of I/O operations, unlike bufq_put.
*/
- bp = dksc->sc_deferred;
- dksc->sc_deferred = NULL;
+ while (dksc->sc_busy > 0) {
- if (bp == NULL)
- bp = bufq_get(dksc->sc_bufq);
+ bp = dksc->sc_deferred;
+ dksc->sc_deferred = NULL;
- while (bp != NULL) {
+ if (bp == NULL)
+ bp = bufq_get(dksc->sc_bufq);
- disk_busy(&dksc->sc_dkdev);
- mutex_exit(&dksc->sc_iolock);
- error = dkd->d_diskstart(dksc->sc_dev, bp);
- mutex_enter(&dksc->sc_iolock);
- if (error == EAGAIN) {
- dksc->sc_deferred = bp;
- disk_unbusy(&dksc->sc_dkdev, 0, (bp->b_flags & B_READ));
- break;
- }
+ while (bp != NULL) {
+
+ disk_busy(&dksc->sc_dkdev);
+ mutex_exit(&dksc->sc_iolock);
+ error = dkd->d_diskstart(dksc->sc_dev, bp);
+ mutex_enter(&dksc->sc_iolock);
+ if (error == EAGAIN) {
+ dksc->sc_deferred = bp;
+ disk_unbusy(&dksc->sc_dkdev, 0, (bp->b_flags & B_READ));
+ break;
+ }
+
+ if (error != 0) {
+ bp->b_error = error;
+ bp->b_resid = bp->b_bcount;
+ dk_done1(dksc, bp, false);
+ }
- if (error != 0) {
- bp->b_error = error;
- bp->b_resid = bp->b_bcount;
- dk_done1(dksc, bp, false);
+ bp = bufq_get(dksc->sc_bufq);
}
- bp = bufq_get(dksc->sc_bufq);
+ dksc->sc_busy--;
}
-
- dksc->sc_busy = false;
done:
mutex_exit(&dksc->sc_iolock);
}
Index: src/sys/dev/dkvar.h
diff -u src/sys/dev/dkvar.h:1.27 src/sys/dev/dkvar.h:1.28
--- src/sys/dev/dkvar.h:1.27 Mon Oct 24 17:14:27 2016
+++ src/sys/dev/dkvar.h Thu Dec 22 13:42:14 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: dkvar.h,v 1.27 2016/10/24 17:14:27 jdolecek Exp $ */
+/* $NetBSD: dkvar.h,v 1.28 2016/12/22 13:42:14 mlelstv Exp $ */
/*-
* Copyright (c) 2002 The NetBSD Foundation, Inc.
@@ -50,7 +50,7 @@ struct dk_softc {
struct bufq_state *sc_bufq; /* buffer queue */
int sc_dtype; /* disk type */
struct buf *sc_deferred; /* retry after start failed */
- bool sc_busy; /* processing buffers */
+ int sc_busy; /* processing buffers */
krndsource_t sc_rnd_source; /* entropy source */
};
Index: src/sys/sys/param.h
diff -u src/sys/sys/param.h:1.518 src/sys/sys/param.h:1.519
--- src/sys/sys/param.h:1.518 Fri Dec 16 23:37:21 2016
+++ src/sys/sys/param.h Thu Dec 22 13:42:14 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: param.h,v 1.518 2016/12/16 23:37:21 riastradh Exp $ */
+/* $NetBSD: param.h,v 1.519 2016/12/22 13:42:14 mlelstv Exp $ */
/*-
* Copyright (c) 1982, 1986, 1989, 1993
@@ -67,7 +67,7 @@
* 2.99.9 (299000900)
*/
-#define __NetBSD_Version__ 799005100 /* NetBSD 7.99.51 */
+#define __NetBSD_Version__ 799005200 /* NetBSD 7.99.52 */
#define __NetBSD_Prereq__(M,m,p) (((((M) * 100000000) + \
(m) * 1000000) + (p) * 100) <= __NetBSD_Version__)