summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2007-07-03 18:18:30 +0000
committerkib <kib@FreeBSD.org>2007-07-03 18:18:30 +0000
commitc88cac4c418f97044c4063d61485f404a44d14e7 (patch)
treebdca5081d32c975c0dfa338ba3fbf619942270c5
parenta5a2c7551bc228c50a49d223e031e75a2a1dff2b (diff)
downloadFreeBSD-src-c88cac4c418f97044c4063d61485f404a44d14e7.zip
FreeBSD-src-c88cac4c418f97044c4063d61485f404a44d14e7.tar.gz
Rev. 1.204 and 1.205 got an erronous version of destroy_dev() that
calls destroy_dev_sched() with cdev mutex locked. Commit the code that was actually tested. Pointy hat to: kib Approved by: re (implicit)
-rw-r--r--sys/kern/kern_conf.c24
1 files changed, 18 insertions, 6 deletions
diff --git a/sys/kern/kern_conf.c b/sys/kern/kern_conf.c
index dba041f..20d3bc3 100644
--- a/sys/kern/kern_conf.c
+++ b/sys/kern/kern_conf.c
@@ -52,7 +52,8 @@ static MALLOC_DEFINE(M_DEVT, "cdev", "cdev storage");
struct mtx devmtx;
static void destroy_devl(struct cdev *dev);
-
+static int destroy_dev_sched_cbl(struct cdev *dev,
+ void (*cb)(void *), void *arg);
static struct cdev *make_dev_credv(int flags,
struct cdevsw *devsw, int minornr,
struct ucred *cr, uid_t uid, gid_t gid, int mode, const char *fmt,
@@ -788,7 +789,7 @@ destroy_dev(struct cdev *dev)
destroy_devl(dev);
dev_unlock_and_free();
} else
- destroy_dev_sched(dev);
+ destroy_dev_sched_cbl(dev, NULL, NULL);
}
const char *
@@ -1014,13 +1015,17 @@ destroy_dev_tq(void *ctx, int pending)
dev_unlock();
}
-int
-destroy_dev_sched_cb(struct cdev *dev, void (*cb)(void *), void *arg)
+/*
+ * devmtx shall be locked on entry. devmtx will be unlocked after
+ * function return.
+ */
+static int
+destroy_dev_sched_cbl(struct cdev *dev, void (*cb)(void *), void *arg)
{
struct cdev_priv *cp;
-
+
+ mtx_assert(&devmtx, MA_OWNED);
cp = dev->si_priv;
- dev_lock();
if (cp->cdp_flags & CDP_SCHED_DTR) {
dev_unlock();
return (0);
@@ -1036,6 +1041,13 @@ destroy_dev_sched_cb(struct cdev *dev, void (*cb)(void *), void *arg)
}
int
+destroy_dev_sched_cb(struct cdev *dev, void (*cb)(void *), void *arg)
+{
+ dev_lock();
+ return (destroy_dev_sched_cbl(dev, cb, arg));
+}
+
+int
destroy_dev_sched(struct cdev *dev)
{
return (destroy_dev_sched_cb(dev, NULL, NULL));
OpenPOWER on IntegriCloud