From 9b444d7bba1ca15869ffb11c9b84051fe6db98f7 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Sun, 18 Mar 2018 21:12:14 -0700 Subject: [PATCH] kernel - Fix deadlock during halt/reboot * Fix a deadlock which occurs between udev and devfs. udev must issue devfs_clone_bitmap_put() outside of the udev_lk. * Fixes numerous shutdown/reboot deadlocks. --- sys/kern/kern_udev.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/sys/kern/kern_udev.c b/sys/kern/kern_udev.c index cd8e9e0e34..4485adcfa9 100644 --- a/sys/kern/kern_udev.c +++ b/sys/kern/kern_udev.c @@ -623,9 +623,9 @@ udev_dev_close(struct dev_close_args *ap) KKASSERT(softc->dev == ap->a_head.a_dev); KKASSERT(softc->opened == 1); + destroy_dev(ap->a_head.a_dev); lockmgr(&udev_lk, LK_EXCLUSIVE); TAILQ_REMOVE(&udevq, softc, entry); - devfs_clone_bitmap_put(&DEVFS_CLONE_BITMAP(udev), softc->unit); if (softc->initiated) { TAILQ_REMOVE(&udev_evq, &softc->marker, link); @@ -639,7 +639,12 @@ udev_dev_close(struct dev_close_args *ap) --udev_open_count; lockmgr(&udev_lk, LK_RELEASE); - destroy_dev(ap->a_head.a_dev); + /* + * WARNING! devfs_clone_bitmap_put() interacts with the devfs + * thread, avoid deadlocks by ensuring we are unlocked + * before calling. + */ + devfs_clone_bitmap_put(&DEVFS_CLONE_BITMAP(udev), softc->unit); wakeup(&udev_evq); kfree(softc, M_UDEV); -- 2.11.4.GIT