Module Name:    src
Committed By:   riastradh
Date:           Mon Mar 20 00:30:03 UTC 2017

Modified Files:
        src/sys/kern: subr_autoconf.c

Log Message:
Make sure we hold alldevs_mtx for access to alldevs in deviter.

- Extend alldevs_mtx section in deviter_init.
- Assert ownership of alldevs_mtx in private functions:
  . deviter_reinit
  . deviter_next1
  . deviter_next2
- Acquire alldevs_mtx in deviter_next.

(alldevs_mtx is not relevant to the struct deviter object, which is
private to the caller who must guarantee exclusive access to it.)


To generate a diff of this commit:
cvs rdiff -u -r1.247 -r1.248 src/sys/kern/subr_autoconf.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/kern/subr_autoconf.c
diff -u src/sys/kern/subr_autoconf.c:1.247 src/sys/kern/subr_autoconf.c:1.248
--- src/sys/kern/subr_autoconf.c:1.247	Tue Jul 19 07:44:03 2016
+++ src/sys/kern/subr_autoconf.c	Mon Mar 20 00:30:03 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: subr_autoconf.c,v 1.247 2016/07/19 07:44:03 msaitoh Exp $ */
+/* $NetBSD: subr_autoconf.c,v 1.248 2017/03/20 00:30:03 riastradh Exp $ */
 
 /*
  * Copyright (c) 1996, 2000 Christopher G. Demetriou
@@ -77,7 +77,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: subr_autoconf.c,v 1.247 2016/07/19 07:44:03 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: subr_autoconf.c,v 1.248 2017/03/20 00:30:03 riastradh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_ddb.h"
@@ -2781,17 +2781,15 @@ deviter_init(deviter_t *di, deviter_flag
 
 	memset(di, 0, sizeof(*di));
 
-	mutex_enter(&alldevs_mtx);
 	if ((flags & DEVITER_F_SHUTDOWN) != 0)
 		flags |= DEVITER_F_RW;
 
+	mutex_enter(&alldevs_mtx);
 	if ((flags & DEVITER_F_RW) != 0)
 		alldevs_nwrite++;
 	else
 		alldevs_nread++;
 	di->di_gen = alldevs_gen++;
-	mutex_exit(&alldevs_mtx);
-
 	di->di_flags = flags;
 
 	switch (di->di_flags & (DEVITER_F_LEAVES_FIRST|DEVITER_F_ROOT_FIRST)) {
@@ -2814,11 +2812,14 @@ deviter_init(deviter_t *di, deviter_flag
 	}
 
 	deviter_reinit(di);
+	mutex_exit(&alldevs_mtx);
 }
 
 static void
 deviter_reinit(deviter_t *di)
 {
+
+	KASSERT(mutex_owned(&alldevs_mtx));
 	if ((di->di_flags & DEVITER_F_RW) != 0)
 		di->di_prev = TAILQ_LAST(&alldevs, devicelist);
 	else
@@ -2828,6 +2829,7 @@ deviter_reinit(deviter_t *di)
 device_t
 deviter_first(deviter_t *di, deviter_flags_t flags)
 {
+
 	deviter_init(di, flags);
 	return deviter_next(di);
 }
@@ -2837,6 +2839,8 @@ deviter_next2(deviter_t *di)
 {
 	device_t dv;
 
+	KASSERT(mutex_owned(&alldevs_mtx));
+
 	dv = di->di_prev;
 
 	if (dv == NULL)
@@ -2855,6 +2859,8 @@ deviter_next1(deviter_t *di)
 {
 	device_t dv;
 
+	KASSERT(mutex_owned(&alldevs_mtx));
+
 	do {
 		dv = deviter_next2(di);
 	} while (dv != NULL && !deviter_visits(di, dv));
@@ -2867,9 +2873,11 @@ deviter_next(deviter_t *di)
 {
 	device_t dv = NULL;
 
+	mutex_enter(&alldevs_mtx);
 	switch (di->di_flags & (DEVITER_F_LEAVES_FIRST|DEVITER_F_ROOT_FIRST)) {
 	case 0:
-		return deviter_next1(di);
+		dv = deviter_next1(di);
+		break;
 	case DEVITER_F_LEAVES_FIRST:
 		while (di->di_curdepth >= 0) {
 			if ((dv = deviter_next1(di)) == NULL) {
@@ -2878,7 +2886,7 @@ deviter_next(deviter_t *di)
 			} else if (dv->dv_depth == di->di_curdepth)
 				break;
 		}
-		return dv;
+		break;
 	case DEVITER_F_ROOT_FIRST:
 		while (di->di_curdepth <= di->di_maxdepth) {
 			if ((dv = deviter_next1(di)) == NULL) {
@@ -2887,10 +2895,13 @@ deviter_next(deviter_t *di)
 			} else if (dv->dv_depth == di->di_curdepth)
 				break;
 		}
-		return dv;
+		break;
 	default:
-		return NULL;
+		break;
 	}
+	mutex_exit(&alldevs_mtx);
+
+	return dv;
 }
 
 void

Reply via email to