Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/pgoyette-localcount]: src/sys/dev First pass at updating the cgd(4) driv...
details: https://anonhg.NetBSD.org/src/rev/b4930a1e7160
branches: pgoyette-localcount
changeset: 852823:b4930a1e7160
user: pgoyette <pgoyette%NetBSD.org@localhost>
date: Wed Jul 20 06:51:13 2016 +0000
description:
First pass at updating the cgd(4) driver for use with localcount(9)
ref-counts.
So far all I've done is to manage the ref-counts. This will defer
removal of the driver from the devsw tables and/or the autoconf tree
while anyone has a reference to any of the device's critical data
(mostly, the softc or the device_t). Note that these ref-counts will
only defer the removal; once the references are released, the removal
will proceed.
On-going work is needed to identify potentially blocking operations,
and to deny any removals if such operations are in-flight. We really
shouldn't be waiting (possibly indefinitely) for these operations to
complete, especially since removals could be attempted by the module(9)
subsystem while holding the kernel_config lock.
diffstat:
sys/dev/cgd.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++----------
1 files changed, 55 insertions(+), 12 deletions(-)
diffs (184 lines):
diff -r e78c990df2b8 -r b4930a1e7160 sys/dev/cgd.c
--- a/sys/dev/cgd.c Wed Jul 20 04:33:53 2016 +0000
+++ b/sys/dev/cgd.c Wed Jul 20 06:51:13 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cgd.c,v 1.108.2.3 2016/07/20 04:33:53 pgoyette Exp $ */
+/* $NetBSD: cgd.c,v 1.108.2.4 2016/07/20 06:51:13 pgoyette Exp $ */
/*-
* Copyright (c) 2002 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cgd.c,v 1.108.2.3 2016/07/20 04:33:53 pgoyette Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cgd.c,v 1.108.2.4 2016/07/20 06:51:13 pgoyette Exp $");
#include <sys/types.h>
#include <sys/param.h>
@@ -176,6 +176,17 @@
/* The code */
+static void
+cgd_release(dev_t dev)
+{
+ int unit = CGDUNIT(dev);
+ device_t self;
+
+ self = device_lookup_acquire(&cgd_cd, unit);
+ if (self != NULL)
+ device_release(self);
+}
+
static struct cgd_softc *
getcgd_softc(dev_t dev)
{
@@ -247,6 +258,7 @@
static struct cgd_softc *
cgd_spawn(int unit)
{
+ device_t self;
cfdata_t cf;
cf = malloc(sizeof(*cf), M_DEVBUF, M_WAITOK);
@@ -255,7 +267,17 @@
cf->cf_unit = unit;
cf->cf_fstate = FSTATE_STAR;
- return device_private(config_attach_pseudo(cf));
+ if (config_attach_pseudo(cf) == NULL)
+ return NULL;
+
+ self = device_lookup_acquire(&cgd_cd, unit);
+ if (self == NULL)
+ return NULL;
+ else
+ /*
+ * Note that we return with a reference to the device!
+ */
+ return device_private(self);
}
static int
@@ -326,23 +348,30 @@
bp->b_error = EINVAL;
bp->b_resid = bp->b_bcount;
biodone(bp);
+ cgd_release(bp->b_dev);
return;
}
/* XXXrcd: Should we test for (cs != NULL)? */
dk_strategy(&cs->sc_dksc, bp);
+ cgd_release(bp->b_dev);
return;
}
static int
cgdsize(dev_t dev)
{
+ int retval;
struct cgd_softc *cs = getcgd_softc(dev);
DPRINTF_FOLLOW(("cgdsize(0x%"PRIx64")\n", dev));
if (!cs)
- return -1;
- return dk_size(&cs->sc_dksc, dev);
+ retval = -1;
+ else
+ retval = dk_size(&cs->sc_dksc, dev);
+
+ cgd_release(dev);
+ return retval;
}
/*
@@ -451,6 +480,7 @@
static void
cgdiodone(struct buf *nbp)
{
+ dev_t dev;
struct buf *obp = nbp->b_private;
struct cgd_softc *cs = getcgd_softc(obp->b_dev);
struct dk_softc *dksc = &cs->sc_dksc;
@@ -494,7 +524,14 @@
if (obp->b_error != 0)
obp->b_resid = obp->b_bcount;
+ /*
+ * copy the dev_t, finish the disk operation, and release the
+ * reference we're holding on to (from cgd_getsoftc() earlier)
+ */
+ dev = obp->b_dev;
dk_done(dksc, obp);
+ cgd_release(dev);
+
dk_start(dksc, NULL);
}
@@ -817,8 +854,10 @@
if (cgu->cgu_unit == -1)
cgu->cgu_unit = unit;
- if (cgu->cgu_unit < 0)
+ if (cgu->cgu_unit < 0) {
+ cgd_release(dev);
return EINVAL; /* XXX: should this be ENXIO? */
+ }
cs = device_lookup_private(&cgd_cd, unit);
if (cs == NULL || !DK_ATTACHED(dksc)) {
@@ -836,6 +875,7 @@
cgu->cgu_mode = cs->sc_cdata.cf_mode;
cgu->cgu_keylen = cs->sc_cdata.cf_keylen;
}
+ cgd_release(dev);
return 0;
}
@@ -1030,7 +1070,7 @@
MODULE(MODULE_CLASS_DRIVER, cgd, "dk_subr");
#ifdef _MODULE
-CFDRIVER_DECL(cgd, DV_DISK, NULL);
+#include "ioconf.c"
#endif
static int
@@ -1051,8 +1091,8 @@
error = config_init_component(cfdriver_ioconf_cgd,
cfattach_ioconf_cgd, cfdata_ioconf_cgd);
if (error) {
- aprint_error("%s: unable to init component",
- cgd_cd.cd_name);
+ aprint_error("%s: unable to init component"
+ ", error %d", cgd_cd.cd_name, error);
break;
}
@@ -1068,8 +1108,8 @@
if (error) {
config_fini_component(cfdriver_ioconf_cgd,
cfattach_ioconf_cgd, cfdata_ioconf_cgd);
- aprint_error("%s: unable to attach devsw",
- cgd_cd.cd_name);
+ aprint_error("%s: unable to attach devsw"
+ ", error %d", cgd_cd.cd_name, error);
}
#endif
break;
@@ -1090,9 +1130,12 @@
/*
* If removal fails, re-attach our {b,c}devsw's
*/
- if (error)
+ if (error) {
+ aprint_error("%s: failed to remove from autoconf"
+ ", error %d", cgd_cd.cd_name, error);
devsw_attach("cgd", &cgd_bdevsw, &bmajor,
&cgd_cdevsw, &cmajor);
+ }
#endif
break;
Home |
Main Index |
Thread Index |
Old Index