diff options
author | kib <kib@FreeBSD.org> | 2007-07-03 17:43:20 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2007-07-03 17:43:20 +0000 |
commit | c3c1199f3c47f28ef2dbb7f35e5ba9a44603f7a3 (patch) | |
tree | ea5abb062e51017d7bdbac9815981ab1438cd85f | |
parent | 0ae42a409556e8dd0fe24abe1db9159f80d1d3a0 (diff) | |
download | FreeBSD-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.c | 10 |
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 * |