Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/pgoyette-localcount]: src/sys Add new xxx_acquire variants for device_lo...



details:   https://anonhg.NetBSD.org/src/rev/0d44b0951cfc
branches:  pgoyette-localcount
changeset: 852794:0d44b0951cfc
user:      pgoyette <pgoyette%NetBSD.org@localhost>
date:      Sat Jul 16 22:06:42 2016 +0000

description:
Add new xxx_acquire variants for device_lookup_private() and
device_find_by_driver_unit_acquire rather than blindly making the old
variants call localcount_acquire().

Also fix a couple of locking sequences.

Thanks to Taylor for the review!

diffstat:

 sys/kern/subr_autoconf.c |  51 +++++++++++++++++++++++++++++++++++++++++------
 sys/sys/device.h         |   4 ++-
 2 files changed, 47 insertions(+), 8 deletions(-)

diffs (126 lines):

diff -r 7d571b568fcb -r 0d44b0951cfc sys/kern/subr_autoconf.c
--- a/sys/kern/subr_autoconf.c  Sat Jul 16 20:40:30 2016 +0000
+++ b/sys/kern/subr_autoconf.c  Sat Jul 16 22:06:42 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: subr_autoconf.c,v 1.246.2.1 2016/07/16 02:13:07 pgoyette Exp $ */
+/* $NetBSD: subr_autoconf.c,v 1.246.2.2 2016/07/16 22:06:42 pgoyette 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.246.2.1 2016/07/16 02:13:07 pgoyette Exp $");
+__KERNEL_RCSID(0, "$NetBSD: subr_autoconf.c,v 1.246.2.2 2016/07/16 22:06:42 pgoyette Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_ddb.h"
@@ -1257,9 +1257,6 @@
 
        KASSERT(mutex_owned(&alldevs_mtx));
 
-       localcount_drain(dev->dv_localcnt, &config_drain_cv,
-           &alldevs_mtx);
-
        /* Unlink from device list.  Link to garbage list. */
        TAILQ_REMOVE(&alldevs, dev, dv_list);
        TAILQ_INSERT_TAIL(garbage, dev, dv_list);
@@ -1267,6 +1264,10 @@
        /* Remove from cfdriver's array. */
        cd->cd_devs[dev->dv_unit] = NULL;
 
+       /* Now wait for references to drain - no new refs are possible */
+       localcount_drain(dev->dv_localcnt, &config_drain_cv,
+           &alldevs_mtx);
+
        /*
         * If the device now has no units in use, unlink its softc array.
         */
@@ -2265,9 +2266,15 @@
 {
        device_t dv;
 
-       dv = device_lookup(cd, unit);
-       if (dv != NULL)
+       mutex_enter(&alldevs_mtx);
+       if (unit < 0 || unit >= cd->cd_ndevs)
+               dv = NULL;
+       else if ((dv = cd->cd_devs[unit]) != NULL && dv->dv_del_gen != 0)
+               dv = NULL;
+       else
                localcount_acquire(dv->dv_localcnt);
+       mutex_exit(&alldevs_mtx);
+
        return dv;
 }
 
@@ -2294,6 +2301,19 @@
 device_lookup_private(cfdriver_t cd, int unit)
 {
 
+       return device_private(device_lookup(cd, unit));
+}
+
+/*
+ * device_lookup_private_acquire:
+ *
+ *     Look up the softc and acquire a reference to the device
+ *     so it won't disappear.
+ */
+void *
+device_lookup_private_acquire(cfdriver_t cd, int unit)
+{
+
        return device_private(device_lookup_acquire(cd, unit));
 }
 
@@ -2330,6 +2350,23 @@
 
        if ((cd = config_cfdriver_lookup(name)) == NULL)
                return NULL;
+       return device_lookup(cd, unit);
+}
+
+/*
+ * device_find_by_driver_unit_acquire:
+ *
+ *     Returns the device of the given driver name and unit or
+ *     NULL if it doesn't exist.  If driver is found, it's
+ *     reference count is incremented so it won't go away.
+ */
+device_t
+device_find_by_driver_unit_acquire(const char *name, int unit)
+{
+       struct cfdriver *cd;
+
+       if ((cd = config_cfdriver_lookup(name)) == NULL)
+               return NULL;
        return device_lookup_acquire(cd, unit);
 }
 
diff -r 7d571b568fcb -r 0d44b0951cfc sys/sys/device.h
--- a/sys/sys/device.h  Sat Jul 16 20:40:30 2016 +0000
+++ b/sys/sys/device.h  Sat Jul 16 22:06:42 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: device.h,v 1.149.2.1 2016/07/16 02:13:08 pgoyette Exp $ */
+/* $NetBSD: device.h,v 1.149.2.2 2016/07/16 22:06:42 pgoyette Exp $ */
 
 /*
  * Copyright (c) 1996, 2000 Christopher G. Demetriou
@@ -493,6 +493,7 @@
 device_t       device_lookup_acquire(cfdriver_t, int);
 void           device_release(device_t);
 void           *device_lookup_private(cfdriver_t, int);
+void           *device_lookup_private_acquire(cfdriver_t, int);
 void           device_register(device_t, void *);
 void           device_register_post_config(device_t, void *);
 
@@ -526,6 +527,7 @@
 
 device_t       device_find_by_xname(const char *);
 device_t       device_find_by_driver_unit(const char *, int);
+device_t       device_find_by_driver_unit_acquire(const char *, int);
 
 bool           device_pmf_is_registered(device_t);
 



Home | Main Index | Thread Index | Old Index