From d92870ddd248e8c2562a8c4047885d3ad221ece7 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Tue, 9 Sep 2008 01:23:03 +0200 Subject: [PATCH] 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 --- drivers/hid/hid-core.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 18b277a833f0..63c8ce5540fe 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); } -- 2.30.2