Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

usb: core: Don't hold the device lock while sleeping in do_proc_control()

Since commit ae8709b296d8 ("USB: core: Make do_proc_control() and
do_proc_bulk() killable") if a device has the USB_QUIRK_DELAY_CTRL_MSG
quirk set, it will temporarily block all other URBs (e.g. interrupts)
while sleeping due to a control.

This results in noticeable delays when, for example, a userspace usbfs
application is sending URB interrupts at a high rate to a keyboard and
simultaneously updates the lock indicators using controls. Interrupts
with direction set to IN are also affected by this, meaning that
delivery of HID reports (containing scancodes) to the usbfs application
is delayed as well.

This patch fixes the regression by calling msleep() while the device
mutex is unlocked, as was the case originally with usb_control_msg().

Fixes: ae8709b296d8 ("USB: core: Make do_proc_control() and do_proc_bulk() killable")
Cc: stable <stable@kernel.org>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Tasos Sahanidis <tasos@tasossah.com>
Link: https://lore.kernel.org/r/3e299e2a-13b9-ddff-7fee-6845e868bc06@tasossah.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Tasos Sahanidis and committed by
Greg Kroah-Hartman
0543e4e8 ab7aa286

+9 -5
+9 -5
drivers/usb/core/devio.c
··· 1209 1209 1210 1210 usb_unlock_device(dev); 1211 1211 i = usbfs_start_wait_urb(urb, tmo, &actlen); 1212 + 1213 + /* Linger a bit, prior to the next control message. */ 1214 + if (dev->quirks & USB_QUIRK_DELAY_CTRL_MSG) 1215 + msleep(200); 1212 1216 usb_lock_device(dev); 1213 1217 snoop_urb(dev, NULL, pipe, actlen, i, COMPLETE, tbuf, actlen); 1214 1218 if (!i && actlen) { 1215 1219 if (copy_to_user(ctrl->data, tbuf, actlen)) { 1216 1220 ret = -EFAULT; 1217 - goto recv_fault; 1221 + goto done; 1218 1222 } 1219 1223 } 1220 1224 } else { ··· 1235 1231 1236 1232 usb_unlock_device(dev); 1237 1233 i = usbfs_start_wait_urb(urb, tmo, &actlen); 1234 + 1235 + /* Linger a bit, prior to the next control message. */ 1236 + if (dev->quirks & USB_QUIRK_DELAY_CTRL_MSG) 1237 + msleep(200); 1238 1238 usb_lock_device(dev); 1239 1239 snoop_urb(dev, NULL, pipe, actlen, i, COMPLETE, NULL, 0); 1240 1240 } ··· 1250 1242 } 1251 1243 ret = (i < 0 ? i : actlen); 1252 1244 1253 - recv_fault: 1254 - /* Linger a bit, prior to the next control message. */ 1255 - if (dev->quirks & USB_QUIRK_DELAY_CTRL_MSG) 1256 - msleep(200); 1257 1245 done: 1258 1246 kfree(dr); 1259 1247 usb_free_urb(urb);