summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2007-07-03 17:43:20 +0000
committerkib <kib@FreeBSD.org>2007-07-03 17:43:20 +0000
commitc3c1199f3c47f28ef2dbb7f35e5ba9a44603f7a3 (patch)
treeea5abb062e51017d7bdbac9815981ab1438cd85f
parent0ae42a409556e8dd0fe24abe1db9159f80d1d3a0 (diff)
downloadFreeBSD-src-c3c1199f3c47f28ef2dbb7f35e5ba9a44603f7a3.zip
FreeBSD-src-c3c1199f3c47f28ef2dbb7f35e5ba9a44603f7a3.tar.gz
Automatically detect deadlock condition in destroy_dev(), that is, if
destroy_dev() is called from csw method, and no d_purge driver method is provided. Transform the direct call to destroy_dev() into destroy_dev_sched(). Reviewed by: njl (programming interface) Debugging help and testing by: Peter Holm Approved by: re (kensmith)
-rw-r--r--sys/kern/kern_conf.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/sys/kern/kern_conf.c b/sys/kern/kern_conf.c
index beacfff..dba041f 100644
--- a/sys/kern/kern_conf.c
+++ b/sys/kern/kern_conf.c
@@ -779,10 +779,16 @@ destroy_devl(struct cdev *dev)
void
destroy_dev(struct cdev *dev)
{
+ struct cdevsw *csw;
dev_lock();
- destroy_devl(dev);
- dev_unlock_and_free();
+ csw = dev->si_devsw;
+ if ((csw != NULL && csw->d_purge != NULL) ||
+ dev->si_threadcount == 0) {
+ destroy_devl(dev);
+ dev_unlock_and_free();
+ } else
+ destroy_dev_sched(dev);
}
const char *
OpenPOWER on IntegriCloud