svn commit: r278290 - in stable/9/sys: fs/devfs kern sys
Hans Petter Selasky
hselasky at FreeBSD.org
Thu Feb 5 21:25:13 UTC 2015
Author: hselasky
Date: Thu Feb 5 21:25:11 2015
New Revision: 278290
URL: https://svnweb.freebsd.org/changeset/base/278290
Log:
MFC r277179, r277199 and r277391:
Add a kernel function to delist our kernel character devices, so that
the device name can be re-used right away in case we are destroying
the character devices in the background.
Modified:
stable/9/sys/fs/devfs/devfs_int.h
stable/9/sys/kern/kern_conf.c
stable/9/sys/sys/conf.h
Directory Properties:
stable/9/sys/ (props changed)
stable/9/sys/dev/ (props changed)
stable/9/sys/fs/ (props changed)
stable/9/sys/sys/ (props changed)
Modified: stable/9/sys/fs/devfs/devfs_int.h
==============================================================================
--- stable/9/sys/fs/devfs/devfs_int.h Thu Feb 5 21:18:44 2015 (r278289)
+++ stable/9/sys/fs/devfs/devfs_int.h Thu Feb 5 21:25:11 2015 (r278290)
@@ -56,6 +56,7 @@ struct cdev_priv {
u_int cdp_flags;
#define CDP_ACTIVE (1 << 0)
#define CDP_SCHED_DTR (1 << 1)
+#define CDP_UNREF_DTR (1 << 2)
u_int cdp_inuse;
u_int cdp_maxdirent;
Modified: stable/9/sys/kern/kern_conf.c
==============================================================================
--- stable/9/sys/kern/kern_conf.c Thu Feb 5 21:18:44 2015 (r278289)
+++ stable/9/sys/kern/kern_conf.c Thu Feb 5 21:25:11 2015 (r278290)
@@ -115,6 +115,8 @@ dev_free_devlocked(struct cdev *cdev)
mtx_assert(&devmtx, MA_OWNED);
cdp = cdev2priv(cdev);
+ KASSERT((cdp->cdp_flags & CDP_UNREF_DTR) == 0,
+ ("destroy_dev() was not called after delist_dev(%p)", cdev));
TAILQ_INSERT_HEAD(&cdevp_free_list, cdp, cdp_list);
}
@@ -1030,6 +1032,7 @@ destroy_devl(struct cdev *dev)
{
struct cdevsw *csw;
struct cdev_privdata *p;
+ struct cdev_priv *cdp;
mtx_assert(&devmtx, MA_OWNED);
KASSERT(dev->si_flags & SI_NAMED,
@@ -1038,13 +1041,22 @@ destroy_devl(struct cdev *dev)
("WARNING: Driver mistake: destroy_dev on eternal %d\n",
dev2unit(dev)));
- devfs_destroy(dev);
+ cdp = cdev2priv(dev);
+ if ((cdp->cdp_flags & CDP_UNREF_DTR) == 0) {
+ /*
+ * Avoid race with dev_rel(), e.g. from the populate
+ * loop. If CDP_UNREF_DTR flag is set, the reference
+ * to be dropped at the end of destroy_devl() was
+ * already taken by delist_dev_locked().
+ */
+ dev_refl(dev);
+
+ devfs_destroy(dev);
+ }
/* Remove name marking */
dev->si_flags &= ~SI_NAMED;
- dev->si_refcount++; /* Avoid race with dev_rel() */
-
/* If we are a child, remove us from the parents list */
if (dev->si_flags & SI_CHILD) {
LIST_REMOVE(dev, si_siblings);
@@ -1100,13 +1112,39 @@ destroy_devl(struct cdev *dev)
}
}
dev->si_flags &= ~SI_ALIAS;
- dev->si_refcount--; /* Avoid race with dev_rel() */
+ cdp->cdp_flags &= ~CDP_UNREF_DTR;
+ dev->si_refcount--;
- if (dev->si_refcount > 0) {
+ if (dev->si_refcount > 0)
LIST_INSERT_HEAD(&dead_cdevsw.d_devs, dev, si_list);
- } else {
+ else
dev_free_devlocked(dev);
- }
+}
+
+static void
+delist_dev_locked(struct cdev *dev)
+{
+ struct cdev_priv *cdp;
+ struct cdev *child;
+
+ mtx_assert(&devmtx, MA_OWNED);
+ cdp = cdev2priv(dev);
+ if ((cdp->cdp_flags & CDP_UNREF_DTR) != 0)
+ return;
+ cdp->cdp_flags |= CDP_UNREF_DTR;
+ dev_refl(dev);
+ devfs_destroy(dev);
+ LIST_FOREACH(child, &dev->si_children, si_siblings)
+ delist_dev_locked(child);
+}
+
+void
+delist_dev(struct cdev *dev)
+{
+
+ dev_lock();
+ delist_dev_locked(dev);
+ dev_unlock();
}
void
Modified: stable/9/sys/sys/conf.h
==============================================================================
--- stable/9/sys/sys/conf.h Thu Feb 5 21:18:44 2015 (r278289)
+++ stable/9/sys/sys/conf.h Thu Feb 5 21:25:11 2015 (r278290)
@@ -247,6 +247,7 @@ void clone_cleanup(struct clonedevs **);
int clone_create(struct clonedevs **, struct cdevsw *, int *unit, struct cdev **dev, int extra);
int count_dev(struct cdev *_dev);
+void delist_dev(struct cdev *_dev);
void destroy_dev(struct cdev *_dev);
int destroy_dev_sched(struct cdev *dev);
int destroy_dev_sched_cb(struct cdev *dev, void (*cb)(void *), void *arg);
More information about the svn-src-stable-9
mailing list