Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys Fix race condition in dksubr, where a dk_start from anot...
details: https://anonhg.NetBSD.org/src/rev/66d21cac4cd1
branches: trunk
changeset: 349763:66d21cac4cd1
user: mlelstv <mlelstv%NetBSD.org@localhost>
date: Thu Dec 22 13:42:14 2016 +0000
description:
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.
diffstat:
sys/dev/dksubr.c | 62 ++++++++++++++++++++++++++++++++-----------------------
sys/dev/dkvar.h | 4 +-
sys/sys/param.h | 4 +-
3 files changed, 40 insertions(+), 30 deletions(-)
diffs (133 lines):
diff -r 2a30c2eba589 -r 66d21cac4cd1 sys/dev/dksubr.c
--- a/sys/dev/dksubr.c Thu Dec 22 13:26:24 2016 +0000
+++ b/sys/dev/dksubr.c Thu Dec 22 13:42:14 2016 +0000
@@ -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 @@
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 @@
* This keeps order of I/O operations, unlike bufq_put.
*/
- bp = dksc->sc_deferred;
- dksc->sc_deferred = NULL;
+ while (dksc->sc_busy > 0) {
+
+ bp = dksc->sc_deferred;
+ dksc->sc_deferred = NULL;
- if (bp == NULL)
- bp = bufq_get(dksc->sc_bufq);
+ if (bp == NULL)
+ bp = bufq_get(dksc->sc_bufq);
- while (bp != NULL) {
+ 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;
+ 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);
+ }
+
+ bp = bufq_get(dksc->sc_bufq);
}
- if (error != 0) {
- bp->b_error = error;
- bp->b_resid = bp->b_bcount;
- dk_done1(dksc, bp, false);
- }
-
- bp = bufq_get(dksc->sc_bufq);
+ dksc->sc_busy--;
}
-
- dksc->sc_busy = false;
done:
mutex_exit(&dksc->sc_iolock);
}
diff -r 2a30c2eba589 -r 66d21cac4cd1 sys/dev/dkvar.h
--- a/sys/dev/dkvar.h Thu Dec 22 13:26:24 2016 +0000
+++ b/sys/dev/dkvar.h Thu Dec 22 13:42:14 2016 +0000
@@ -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 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 */
};
diff -r 2a30c2eba589 -r 66d21cac4cd1 sys/sys/param.h
--- a/sys/sys/param.h Thu Dec 22 13:26:24 2016 +0000
+++ b/sys/sys/param.h Thu Dec 22 13:42:14 2016 +0000
@@ -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__)
Home |
Main Index |
Thread Index |
Old Index