|
@@ -5177,6 +5177,7 @@ int usb_reset_device(struct usb_device *udev)
|
|
|
{
|
|
|
int ret;
|
|
|
int i;
|
|
|
+ unsigned int noio_flag;
|
|
|
struct usb_host_config *config = udev->actconfig;
|
|
|
|
|
|
if (udev->state == USB_STATE_NOTATTACHED ||
|
|
@@ -5186,6 +5187,17 @@ int usb_reset_device(struct usb_device *udev)
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
|
|
|
+ /*
|
|
|
+ * Don't allocate memory with GFP_KERNEL in current
|
|
|
+ * context to avoid possible deadlock if usb mass
|
|
|
+ * storage interface or usbnet interface(iSCSI case)
|
|
|
+ * is included in current configuration. The easist
|
|
|
+ * approach is to do it for every device reset,
|
|
|
+ * because the device 'memalloc_noio' flag may have
|
|
|
+ * not been set before reseting the usb device.
|
|
|
+ */
|
|
|
+ noio_flag = memalloc_noio_save();
|
|
|
+
|
|
|
/* Prevent autosuspend during the reset */
|
|
|
usb_autoresume_device(udev);
|
|
|
|
|
@@ -5230,6 +5242,7 @@ int usb_reset_device(struct usb_device *udev)
|
|
|
}
|
|
|
|
|
|
usb_autosuspend_device(udev);
|
|
|
+ memalloc_noio_restore(noio_flag);
|
|
|
return ret;
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(usb_reset_device);
|