HID: usbhid: fix a lockup in usbhid_disconnect()
Occasionally, hid_reset() couldn't bring device back to alive. In this
case, usbhid driver starts the procedure to disconnect the device from
HID core. However, a lockup shows in below stack trace can happen.
[ 35.415519] kworker/0:3 D
ffffffc00008691c 0 244 2 0x00000000
[ 35.422591] Workqueue: events hid_reset
[ 35.426433] Call trace:
[ 35.428879] [<
ffffffc00008691c>] __switch_to+0xc8/0xd4
[ 35.434013] [<
ffffffc000c6019c>] __schedule+0x668/0x808
[ 35.439231] [<
ffffffc000c60394>] schedule+0x58/0x60
[ 35.444107] [<
ffffffc000c5d8b8>] schedule_timeout+0x2c/0x260
[ 35.449761] [<
ffffffc000c5f908>] wait_for_common+0x134/0x170
[ 35.455413] [<
ffffffc000c5f958>] wait_for_completion+0x14/0x1c
[ 35.461240] [<
ffffffc0000cba6c>] flush_work+0x1cc/0x27c
[ 35.466459] [<
ffffffc0000cbcec>] __cancel_work_timer+0x130/0x1b4
[ 35.472460] [<
ffffffc0000cbd80>] cancel_work_sync+0x10/0x18
[ 35.478027] [<
ffffffc00093506c>] usbhid_close+0x64/0xa8
[ 35.483248] [<
ffffffc00090db24>] hidinput_close+0x1c/0x24
[ 35.488644] [<
ffffffc0007d0c44>] input_close_device+0x50/0x7c
[ 35.494383] [<
ffffffc0007f8088>] cfb_input_disconnect+0x14/0x30
[ 35.500297] [<
ffffffc0007d22dc>] __input_unregister_device+0xb8/0x158
[ 35.506729] [<
ffffffc0007d243c>] input_unregister_device+0x58/0x70
[ 35.512902] [<
ffffffc000910ef4>] hidinput_disconnect+0x5c/0x84
[ 35.518728] [<
ffffffc00090b7e0>] hid_disconnect+0x34/0x64
[ 35.524119] [<
ffffffc00090b880>] hid_device_remove+0x70/0xc4
[ 35.529773] [<
ffffffc00055109c>] __device_release_driver+0x94/0xe4
[ 35.535945] [<
ffffffc000551114>] device_release_driver+0x28/0x3c
[ 35.541947] [<
ffffffc000550890>] bus_remove_device+0x14c/0x170
[ 35.547773] [<
ffffffc00054dc7c>] device_del+0x140/0x1a0
[ 35.552990] [<
ffffffc00090bb8c>] hid_destroy_device+0x28/0x60
[ 35.558729] [<
ffffffc000935e10>] usbhid_disconnect+0x68/0x80
[ 35.564383] [<
ffffffc00074e740>] usb_unbind_interface+0x78/0x17c
[ 35.570380] [<
ffffffc00055109c>] __device_release_driver+0x94/0xe4
[ 35.576552] [<
ffffffc000551114>] device_release_driver+0x28/0x3c
[ 35.582552] [<
ffffffc00074e890>] usb_driver_release_interface+0x4c/0x80
[ 35.589158] [<
ffffffc00074e910>] usb_forced_unbind_intf+0x4c/0x64
[ 35.595244] [<
ffffffc00074e970>] unbind_marked_interfaces.isra.6+0x48/0x64
[ 35.602109] [<
ffffffc00074ead4>] usb_unbind_and_rebind_marked_interfaces+0x18/0x2c
[ 35.609670] [<
ffffffc000742168>] usb_reset_device+0x144/0x1ac
[ 35.615408] [<
ffffffc000936c34>] hid_reset+0xf8/0x19c
[ 35.620453] [<
ffffffc0000cb054>] process_one_work+0x2c8/0x4cc
[ 35.626192] [<
ffffffc0000cc418>] worker_thread+0x204/0x378
[ 35.631670] [<
ffffffc0000d2e04>] kthread+0xc0/0xc8
This commit introduce a disconnect bottom half worker function to HID device clean up
in another context so that the lock up can be avoided.
bug
1747873
Change-Id: I7e3b19a7cae4da6d33d26eb9e3bb332d2226a5f1
Signed-off-by: JC Kuo <jckuo@nvidia.com>
Reviewed-on: http://git-master/r/
1118881
Reviewed-by: BH Hsieh <bhsieh@nvidia.com>
Reviewed-by: ChihMin Cheng <ccheng@nvidia.com>
GVS: Gerrit_Virtual_Submit
Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
Reviewed-by: Vinayak Pane <vpane@nvidia.com>
Reviewed-by: Ashutosh Jha <ajha@nvidia.com>