HID: fix possible deadlock in usbhid_close()
authorOliver Neukum <oliver@neukum.org>
Wed, 29 Apr 2009 15:12:12 +0000 (17:12 +0200)
committerJiri Kosina <jkosina@suse.cz>
Wed, 29 Apr 2009 15:25:01 +0000 (17:25 +0200)
This patch switches usbhid_close() from flush_scheduled_work() to canceling
the outstanding work. This fixes a possible deadlock due to work taking
the mutex usbhid_close() holds. Lockdep reported the problem.

Signed-off-by: Oliver Neukum <oliver@neukum.org>
--
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
drivers/hid/usbhid/hid-core.c

index 4306cb1b8ce5c91275be6566825ce02ec6f210fb..900ce18dd5490a4982e2f495693a9da8684e96e5 100644 (file)
@@ -662,8 +662,8 @@ void usbhid_close(struct hid_device *hid)
        spin_lock_irq(&usbhid->lock);
        if (!--hid->open) {
                spin_unlock_irq(&usbhid->lock);
        spin_lock_irq(&usbhid->lock);
        if (!--hid->open) {
                spin_unlock_irq(&usbhid->lock);
+               hid_cancel_delayed_stuff(usbhid);
                usb_kill_urb(usbhid->urbin);
                usb_kill_urb(usbhid->urbin);
-               flush_scheduled_work();
                usbhid->intf->needs_remote_wakeup = 0;
        } else {
                spin_unlock_irq(&usbhid->lock);
                usbhid->intf->needs_remote_wakeup = 0;
        } else {
                spin_unlock_irq(&usbhid->lock);