Sat, 12 Dec 2020 14:33:12 -0800
Looks like urb is submitted again before invoking the
urb->complete(urb) callback for the previous submit.
If the warning is not benign, fix it by moving the wakeup in IRQ to
the urb complete callback. Because it is a sync submit, usb_yurex's
io_mutex helps to ensure urb will not be submitted again before it is
dequeued from the usb core.
Though the sync submit explains the latency introduced, any thoughts
to cut it are highly appreciated.
--- a/drivers/usb/misc/yurex.c
+++ b/drivers/usb/misc/yurex.c
@@ -78,13 +78,11 @@ static void yurex_control_callback(struc
struct usb_yurex *dev = urb->context;
int status = urb->status;
- if (status) {
+ if (status)
dev_err(&urb->dev->dev, "%s - control failed: %d\n",
__func__, status);
- wake_up_interruptible(&dev->waitq);
- return;
- }
- /* on success, sender woken up by CMD_ACK int in, or timeout */
+
+ wake_up_interruptible(&dev->waitq);
}
static void yurex_delete(struct kref *kref)
@@ -177,7 +175,6 @@ static void yurex_interrupt(struct urb *
case CMD_ACK:
dev_dbg(&dev->interface->dev, "%s ack: %c\n",
__func__, buf[1]);
- wake_up_interruptible(&dev->waitq);
break;
}
@@ -489,13 +486,14 @@ static ssize_t yurex_write(struct file *
}
/* send the data as the control msg */
- prepare_to_wait(&dev->waitq, &wait, TASK_INTERRUPTIBLE);
dev_dbg(&dev->interface->dev, "%s - submit %c\n", __func__,
dev->cntl_buffer[0]);
retval = usb_submit_urb(dev->cntl_urb, GFP_ATOMIC);
- if (retval >= 0)
+ if (retval >= 0) {
+ prepare_to_wait(&dev->waitq, &wait, TASK_INTERRUPTIBLE);
timeout = schedule_timeout(YUREX_WRITE_TIMEOUT);
- finish_wait(&dev->waitq, &wait);
+ finish_wait(&dev->waitq, &wait);
+ }
mutex_unlock(&dev->io_mutex);