Skip to contentSkip to conversation

usb: gadget: core: flush gadget workqueue after device removal

PATCH Superseded Roy Luo 2 participants 3 messages Feb 4, 2025 USB

v1 of 2 Superseded Latest is v2 →

lore
Share & tools
lore

Roy Luo

author
#0 lore raw

PATCH 1/1 usb: gadget: core: flush gadget workqueue after device removal

usb_del_gadget() can lead to new work being scheduled in gadget->work workqueue. This is observed, for example, with the dwc3 driver with the following call stack:
device_del()

    gadget_unbind_driver()
      usb_gadget_disconnect_locked()
        dwc3_gadget_pullup()
	  dwc3_gadget_soft_disconnect()
	    usb_gadget_set_state()
	      schedule_work(&gadget->work)

Move flush_work() after device_del() to ensure the workqueue is cleaned up.

Fixes 1ff24d40b3c3 ("usb: dwc3: gadget: Fix incorrect UDC state after manual deconfiguration")
---
 drivers/usb/gadget/udc/core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/gadget/udc/core.c +1 -1
index a6f46364be65..4b3d5075621a 100644
@@ -1543,8 +1543,8 @@ void usb_del_gadget(struct usb_gadget *gadget)
 
 	kobject_uevent(&udc->dev.kobj, KOBJ_REMOVE);
 	sysfs_remove_link(&udc->dev.kobj, "gadget");
-	flush_work(&gadget->work);
 	device_del(&gadget->dev);
+	flush_work(&gadget->work);
 	ida_free(&gadget_id_numbers, gadget->id_number);
 	cancel_work_sync(&udc->vbus_work);
 	device_unregister(&udc->dev);

base-commit: f286757b644c226b6b31779da95a4fa7ab245ef5

Signature · 1 line
2.48.1.362.g079036d154-goog
#1 lore raw
Quoted 11 lines · Roy Luo

usb_del_gadget() can lead to new work being scheduled in gadget->work workqueue. This is observed, for example, with the dwc3 driver with the following call stack:
device_del()

    gadget_unbind_driver()
      usb_gadget_disconnect_locked()
        dwc3_gadget_pullup()
	  dwc3_gadget_soft_disconnect()
	    usb_gadget_set_state()
	      schedule_work(&gadget->work)
Quoted 4 lines

Move flush_work() after device_del() to ensure the workqueue is cleaned up.

Fixes 1ff24d40b3c3 ("usb: dwc3: gadget: Fix incorrect UDC state after manual deconfiguration")

The reference should be targeting the udc core. Probably want to Cc stable also.

BR,
Thinh

Quoted 24 lines
---
 drivers/usb/gadget/udc/core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/gadget/udc/core.c +1 -1
index a6f46364be65..4b3d5075621a 100644
@@ -1543,8 +1543,8 @@ void usb_del_gadget(struct usb_gadget *gadget)
 
 	kobject_uevent(&udc->dev.kobj, KOBJ_REMOVE);
 	sysfs_remove_link(&udc->dev.kobj, "gadget");
-	flush_work(&gadget->work);
 	device_del(&gadget->dev);
+	flush_work(&gadget->work);
 	ida_free(&gadget_id_numbers, gadget->id_number);
 	cancel_work_sync(&udc->vbus_work);
 	device_unregister(&udc->dev);

base-commit: f286757b644c226b6b31779da95a4fa7ab245ef5

Signature · 1 line
2.48.1.362.g079036d154-goog
author
#2 lore raw
Quoted 13 lines · Thinh Nguyen
Quoted 11 lines · Roy Luo

usb_del_gadget() can lead to new work being scheduled in gadget->work workqueue. This is observed, for example, with the dwc3 driver with the following call stack:
device_del()

    gadget_unbind_driver()
      usb_gadget_disconnect_locked()
        dwc3_gadget_pullup()
        dwc3_gadget_soft_disconnect()
          usb_gadget_set_state()
            schedule_work(&gadget->work)
Quoted 8 lines
Quoted 4 lines

Move flush_work() after device_del() to ensure the workqueue is cleaned up.

Fixes 1ff24d40b3c3 ("usb: dwc3: gadget: Fix incorrect UDC state after manual deconfiguration")

The reference should be targeting the udc core. Probably want to Cc stable also.

Thanks for the review, sending out v2.

Regards,
Roy Luo