Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys driver(9): New devsw members d_cfdriver, d_devtounit.
details: https://anonhg.NetBSD.org/src/rev/4c41194fe8cc
branches: trunk
changeset: 364492:4c41194fe8cc
user: riastradh <riastradh%NetBSD.org@localhost>
date: Mon Mar 28 12:33:50 2022 +0000
description:
driver(9): New devsw members d_cfdriver, d_devtounit.
If set, then bdev_open/cdev_open will use d_devtounit to map the
dev_t to an autoconf instance (e.g., /dev/wd0a -> wd0) and hold a
reference with device_lookup_acquire across the call to d_open.
This guarantees that the autoconf instance cannot be detached while
the devsw's d_open function is trying to open it (and also that the
autoconf instance has finished *_attach before anyone can open it).
Of course, if the underlying hardware has gone away, there will be
I/O errors, but this avoids software synchronization bugs between
open and detach for drivers that opt into it. It's up to the driver
and bus to figure out how to deal with I/O errors from operations on
hardware that has gone away while the software hasn't finished
notifying everything that it's gone yet.
XXX kernel ABI change to struct bdevsw/cdevsw requires bump
diffstat:
sys/kern/subr_devsw.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++---
sys/sys/conf.h | 6 ++++-
2 files changed, 54 insertions(+), 5 deletions(-)
diffs (133 lines):
diff -r 140800c3aa80 -r 4c41194fe8cc sys/kern/subr_devsw.c
--- a/sys/kern/subr_devsw.c Mon Mar 28 12:33:41 2022 +0000
+++ b/sys/kern/subr_devsw.c Mon Mar 28 12:33:50 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: subr_devsw.c,v 1.40 2022/03/28 12:33:32 riastradh Exp $ */
+/* $NetBSD: subr_devsw.c,v 1.41 2022/03/28 12:33:50 riastradh Exp $ */
/*-
* Copyright (c) 2001, 2002, 2007, 2008 The NetBSD Foundation, Inc.
@@ -69,7 +69,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: subr_devsw.c,v 1.40 2022/03/28 12:33:32 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: subr_devsw.c,v 1.41 2022/03/28 12:33:50 riastradh Exp $");
#ifdef _KERNEL_OPT
#include "opt_dtrace.h"
@@ -89,6 +89,7 @@
#include <sys/localcount.h>
#include <sys/pserialize.h>
#include <sys/xcall.h>
+#include <sys/device.h>
#ifdef DEVSW_DEBUG
#define DPRINTF(x) printf x
@@ -895,16 +896,38 @@
{
const struct bdevsw *d;
struct localcount *lc;
- int rv, mpflag;
+ device_t dv = NULL/*XXXGCC*/;
+ int unit, rv, mpflag;
d = bdevsw_lookup_acquire(dev, &lc);
if (d == NULL)
return ENXIO;
+ if (d->d_devtounit) {
+ /*
+ * If the device node corresponds to an autoconf device
+ * instance, acquire a reference to it so that during
+ * d_open, device_lookup is stable.
+ *
+ * XXX This should also arrange to instantiate cloning
+ * pseudo-devices if appropriate, but that requires
+ * reviewing them all to find and verify a common
+ * pattern.
+ */
+ if ((unit = (*d->d_devtounit)(dev)) == -1)
+ return ENXIO;
+ if ((dv = device_lookup_acquire(d->d_cfdriver, unit)) == NULL)
+ return ENXIO;
+ }
+
DEV_LOCK(d);
rv = (*d->d_open)(dev, flag, devtype, l);
DEV_UNLOCK(d);
+ if (d->d_devtounit) {
+ device_release(dv);
+ }
+
bdevsw_release(d, lc);
return rv;
@@ -1050,16 +1073,38 @@
{
const struct cdevsw *d;
struct localcount *lc;
- int rv, mpflag;
+ device_t dv = NULL/*XXXGCC*/;
+ int unit, rv, mpflag;
d = cdevsw_lookup_acquire(dev, &lc);
if (d == NULL)
return ENXIO;
+ if (d->d_devtounit) {
+ /*
+ * If the device node corresponds to an autoconf device
+ * instance, acquire a reference to it so that during
+ * d_open, device_lookup is stable.
+ *
+ * XXX This should also arrange to instantiate cloning
+ * pseudo-devices if appropriate, but that requires
+ * reviewing them all to find and verify a common
+ * pattern.
+ */
+ if ((unit = (*d->d_devtounit)(dev)) == -1)
+ return ENXIO;
+ if ((dv = device_lookup_acquire(d->d_cfdriver, unit)) == NULL)
+ return ENXIO;
+ }
+
DEV_LOCK(d);
rv = (*d->d_open)(dev, flag, devtype, l);
DEV_UNLOCK(d);
+ if (d->d_devtounit) {
+ device_release(dv);
+ }
+
cdevsw_release(d, lc);
return rv;
diff -r 140800c3aa80 -r 4c41194fe8cc sys/sys/conf.h
--- a/sys/sys/conf.h Mon Mar 28 12:33:41 2022 +0000
+++ b/sys/sys/conf.h Mon Mar 28 12:33:50 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: conf.h,v 1.155 2022/03/28 12:33:22 riastradh Exp $ */
+/* $NetBSD: conf.h,v 1.156 2022/03/28 12:33:50 riastradh Exp $ */
/*-
* Copyright (c) 1990, 1993
@@ -76,6 +76,8 @@
int (*d_dump)(dev_t, daddr_t, void *, size_t);
int (*d_psize)(dev_t);
int (*d_discard)(dev_t, off_t, off_t);
+ int (*d_devtounit)(dev_t);
+ struct cfdriver *d_cfdriver;
int d_flag;
};
@@ -94,6 +96,8 @@
paddr_t (*d_mmap)(dev_t, off_t, int);
int (*d_kqfilter)(dev_t, struct knote *);
int (*d_discard)(dev_t, off_t, off_t);
+ int (*d_devtounit)(dev_t);
+ struct cfdriver *d_cfdriver;
int d_flag;
};
Home |
Main Index |
Thread Index |
Old Index