From: Jiri Slaby Date: Mon, 8 Sep 2008 23:23:03 +0000 (+0200) Subject: HID: fix tty<->hid deadlock X-Git-Tag: v2.6.28-rc1~571^2~17 X-Git-Url: http://pilppa.com/gitweb/?a=commitdiff_plain;h=d92870ddd248e8c2562a8c4047885d3ad221ece7;p=linux-2.6-omap-h63xx.git HID: fix tty<->hid deadlock hid_compat_load() runs on the default workqueue, it request_module(), it execs modprobe, it exits, tty flushes default workqueue, it hangs, because we are still in it. Signed-off-by: Jiri Slaby Tested-by: Signed-off-by: Andrew Morton Signed-off-by: Jiri Kosina --- diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 18b277a833f..63c8ce5540f 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1657,6 +1657,7 @@ static void hid_compat_load(struct work_struct *ws) request_module("hid-dummy"); } static DECLARE_WORK(hid_compat_work, hid_compat_load); +static struct workqueue_struct *hid_compat_wq; #endif static int __init hid_init(void) @@ -1674,7 +1675,12 @@ static int __init hid_init(void) goto err_bus; #ifdef CONFIG_HID_COMPAT - schedule_work(&hid_compat_work); + hid_compat_wq = create_workqueue("hid_compat"); + if (!hid_compat_wq) { + hidraw_exit(); + goto err; + } + queue_work(hid_compat_wq, &hid_compat_work); #endif return 0; @@ -1686,6 +1692,9 @@ err: static void __exit hid_exit(void) { +#ifdef CONFIG_HID_COMPAT + destroy_workqueue(hid_compat_wq); +#endif hidraw_exit(); bus_unregister(&hid_bus_type); }