[PATCH 2/2] usbip: identify the event handler with current_work()
From: Michael Grzeschik
Date: Wed Nov 11 2026 - 06:35:23 EST
usbip_in_eh() compares the task with worker_context, the first worker
that ever ran the event handler. Workers of the unbound usbip_event
workqueue are reaped when idle and new ones run the handler later, so the
check fails inside the event handler, and the remembered task_struct may
be reused by any other task, which then wrongly counts as the event
handler. stub_disconnect() relies on it to skip the shutdown of a device
reset from the event handler.
Ask the workqueue which work item the current task executes instead.
Signed-off-by: Michael Grzeschik <grzeschik@xxxxxxxxx>
---
drivers/usb/usbip/usbip_event.c | 11 ++---------
1 file changed, 2 insertions(+), 9 deletions(-)
diff --git a/drivers/usb/usbip/usbip_event.c b/drivers/usb/usbip/usbip_event.c
index eea9a71f0eac..e00bc535a822 100644
--- a/drivers/usb/usbip/usbip_event.c
+++ b/drivers/usb/usbip/usbip_event.c
@@ -57,16 +57,11 @@ static struct usbip_device *get_event(void)
return ud;
}
-static struct task_struct *worker_context;
static void event_handler(struct work_struct *work)
{
struct usbip_device *ud;
- if (worker_context == NULL) {
- worker_context = current;
- }
-
while ((ud = get_event()) != NULL) {
usbip_dbg_eh("pending event %lx\n", ud->event);
@@ -194,9 +189,7 @@ EXPORT_SYMBOL_GPL(usbip_event_happened);
int usbip_in_eh(struct task_struct *task)
{
- if (task == worker_context)
- return 1;
-
- return 0;
+ /* only the worker running usbip_work is the event handler */
+ return task == current && current_work() == &usbip_work;
}
EXPORT_SYMBOL_GPL(usbip_in_eh);
--
2.53.0