Module Name:    src
Committed By:   ad
Date:           Thu Sep  7 20:07:04 UTC 2023

Modified Files:
        src/sys/dev/i2o: dpti.c iop.c

Log Message:
Make the I2O management cdevs MPSAFE.


To generate a diff of this commit:
cvs rdiff -u -r1.50 -r1.51 src/sys/dev/i2o/dpti.c
cvs rdiff -u -r1.92 -r1.93 src/sys/dev/i2o/iop.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/dev/i2o/dpti.c
diff -u src/sys/dev/i2o/dpti.c:1.50 src/sys/dev/i2o/dpti.c:1.51
--- src/sys/dev/i2o/dpti.c:1.50	Mon Sep  3 16:29:31 2018
+++ src/sys/dev/i2o/dpti.c	Thu Sep  7 20:07:03 2023
@@ -1,7 +1,7 @@
-/*	$NetBSD: dpti.c,v 1.50 2018/09/03 16:29:31 riastradh Exp $	*/
+/*	$NetBSD: dpti.c,v 1.51 2023/09/07 20:07:03 ad Exp $	*/
 
 /*-
- * Copyright (c) 2001, 2007 The NetBSD Foundation, Inc.
+ * Copyright (c) 2001, 2007, 2023 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
@@ -57,7 +57,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: dpti.c,v 1.50 2018/09/03 16:29:31 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: dpti.c,v 1.51 2023/09/07 20:07:03 ad Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -66,7 +66,7 @@ __KERNEL_RCSID(0, "$NetBSD: dpti.c,v 1.5
 #include <sys/queue.h>
 #include <sys/proc.h>
 #include <sys/endian.h>
-#include <sys/malloc.h>
+#include <sys/kmem.h>
 #include <sys/conf.h>
 #include <sys/ioctl.h>
 #include <sys/kauth.h>
@@ -150,7 +150,7 @@ const struct cdevsw dpti_cdevsw = {
 	.d_mmap = nommap,
 	.d_kqfilter = nokqfilter,
 	.d_discard = nodiscard,
-	.d_flag = D_OTHER,
+	.d_flag = D_OTHER | D_MPSAFE,
 };
 
 CFATTACH_DECL_NEW(dpti, sizeof(struct dpti_softc),
@@ -242,6 +242,7 @@ dptiioctl(dev_t dev, u_long cmd, void *d
 		linux = 0;
 	}
 
+	mutex_enter(&iop->sc_conflock);
 	switch (cmd) {
 	case DPT_SIGNATURE:
 		if (size > sizeof(dpti_sig))
@@ -283,13 +284,11 @@ dptiioctl(dev_t dev, u_long cmd, void *d
 		if (rv)
 			break;
 
-		mutex_enter(&iop->sc_conflock);
 		if (linux) {
 			rv = dpti_passthrough(sc, data, l->l_proc);
 		} else {
 			rv = dpti_passthrough(sc, *(void **)data, l->l_proc);
 		}
-		mutex_exit(&iop->sc_conflock);
 		break;
 
 	case DPT_I2ORESETCMD:
@@ -299,15 +298,14 @@ dptiioctl(dev_t dev, u_long cmd, void *d
 		break;
 
 	case DPT_I2ORESCANCMD:
-		mutex_enter(&iop->sc_conflock);
 		rv = iop_reconfigure(iop, 0);
-		mutex_exit(&iop->sc_conflock);
 		break;
 
 	default:
 		rv = ENOTTY;
 		break;
 	}
+	mutex_exit(&iop->sc_conflock);
 
 	return (rv);
 }
@@ -644,13 +642,7 @@ dpti_passthrough(struct dpti_softc *sc, 
 			}
 
 			bufs[nbuf].db_size = sz;
-			bufs[nbuf].db_ptr = malloc(sz, M_DEVBUF, M_WAITOK);
-			if (bufs[nbuf].db_ptr == NULL) {
-				DPRINTF(("%s: allocation failure\n",
-				    device_xname(sc->sc_dev)));
-				rv = ENOMEM;
-				goto bad;
-			}
+			bufs[nbuf].db_ptr = kmem_zalloc(sz, KM_SLEEP);
 
 			for (i = 0, sz = 0; i < bufs[nbuf].db_nfrag; i++) {
 				rv = copyin(bufs[nbuf].db_frags[i].iov_base,
@@ -744,7 +736,7 @@ dpti_passthrough(struct dpti_softc *sc, 
 		}
 
 		if (bufs[i].db_ptr != NULL)
-			free(bufs[i].db_ptr, M_DEVBUF);
+			kmem_free(bufs[i].db_ptr, bufs[i].db_size);
 	}
 
 	return (rv);

Index: src/sys/dev/i2o/iop.c
diff -u src/sys/dev/i2o/iop.c:1.92 src/sys/dev/i2o/iop.c:1.93
--- src/sys/dev/i2o/iop.c:1.92	Sat Aug  7 16:19:11 2021
+++ src/sys/dev/i2o/iop.c	Thu Sep  7 20:07:03 2023
@@ -1,7 +1,7 @@
-/*	$NetBSD: iop.c,v 1.92 2021/08/07 16:19:11 thorpej Exp $	*/
+/*	$NetBSD: iop.c,v 1.93 2023/09/07 20:07:03 ad Exp $	*/
 
 /*-
- * Copyright (c) 2000, 2001, 2002, 2007 The NetBSD Foundation, Inc.
+ * Copyright (c) 2000, 2001, 2002, 2007, 2023 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: iop.c,v 1.92 2021/08/07 16:19:11 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: iop.c,v 1.93 2023/09/07 20:07:03 ad Exp $");
 
 #include "iop.h"
 
@@ -106,7 +106,7 @@ const struct cdevsw iop_cdevsw = {
 	.d_mmap = nommap,
 	.d_kqfilter = nokqfilter,
 	.d_discard = nodiscard,
-	.d_flag = D_OTHER,
+	.d_flag = D_OTHER | D_MPSAFE,
 };
 
 #define	IC_CONFIGURE	0x01
@@ -2438,16 +2438,23 @@ int
 iopopen(dev_t dev, int flag, int mode, struct lwp *l)
 {
 	struct iop_softc *sc;
+	int rv;
 
 	if ((sc = device_lookup_private(&iop_cd, minor(dev))) == NULL)
 		return (ENXIO);
+
+	mutex_enter(&sc->sc_conflock);
 	if ((sc->sc_flags & IOP_ONLINE) == 0)
-		return (ENXIO);
-	if ((sc->sc_flags & IOP_OPEN) != 0)
-		return (EBUSY);
-	sc->sc_flags |= IOP_OPEN;
+		rv = ENXIO;
+	else if ((sc->sc_flags & IOP_OPEN) != 0)
+		rv = EBUSY;
+	else {
+		sc->sc_flags |= IOP_OPEN;
+		rv = 0;
+	}
+	mutex_exit(&sc->sc_conflock);
 
-	return (0);
+	return (rv);
 }
 
 int
@@ -2457,7 +2464,10 @@ iopclose(dev_t dev, int flag, int mode,
 	struct iop_softc *sc;
 
 	sc = device_lookup_private(&iop_cd, minor(dev));
+
+	mutex_enter(&sc->sc_conflock);
 	sc->sc_flags &= ~IOP_OPEN;
+	mutex_exit(&sc->sc_conflock);
 
 	return (0);
 }
@@ -2472,14 +2482,19 @@ iopioctl(dev_t dev, u_long cmd, void *da
 	sc = device_lookup_private(&iop_cd, minor(dev));
 	rv = 0;
 
+	mutex_enter(&sc->sc_conflock);
 	switch (cmd) {
 	case IOPIOCPT:
 		rv = kauth_authorize_device_passthru(l->l_cred, dev,
 		    KAUTH_REQ_DEVICE_RAWIO_PASSTHRU_ALL, data);
-		if (rv)
+		if (rv) {
+			mutex_exit(&sc->sc_conflock);
 			return (rv);
+		}
 
-		return (iop_passthrough(sc, (struct ioppt *)data, l->l_proc));
+		rv = iop_passthrough(sc, (struct ioppt *)data, l->l_proc);
+		mutex_exit(&sc->sc_conflock);
+		return (rv);
 
 	case IOPIOCGSTATUS:
 		iov = (struct iovec *)data;
@@ -2490,6 +2505,7 @@ iopioctl(dev_t dev, u_long cmd, void *da
 			iov->iov_len = i;
 		if ((rv = iop_status_get(sc, 0)) == 0)
 			rv = copyout(&sc->sc_status, iov->iov_base, i);
+		mutex_exit(&sc->sc_conflock);
 		return (rv);
 
 	case IOPIOCGLCT:
@@ -2501,11 +2517,10 @@ iopioctl(dev_t dev, u_long cmd, void *da
 #if defined(DIAGNOSTIC) || defined(I2ODEBUG)
 		printf("%s: unknown ioctl %lx\n", device_xname(sc->sc_dev), cmd);
 #endif
+		mutex_exit(&sc->sc_conflock);
 		return (ENOTTY);
 	}
 
-	mutex_enter(&sc->sc_conflock);
-
 	switch (cmd) {
 	case IOPIOCGLCT:
 		iov = (struct iovec *)data;
@@ -2544,6 +2559,8 @@ iop_passthrough(struct iop_softc *sc, st
 	struct ioppt_buf *ptb;
 	int rv, i, mapped;
 
+	KASSERT(mutex_owned(&sc->sc_conflock));
+
 	mf = NULL;
 	im = NULL;
 	mapped = 1;

Reply via email to