Revert "usb: gadget: uvc: rework pump worker to avoid while loop"
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 5 Oct 2023 08:50:57 +0000 (10:50 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 5 Oct 2023 08:52:29 +0000 (10:52 +0200)
This reverts commit bb00788bd62778ef80a97d67a0e3c569ac6be06f.

Based on review comments, it was applied too soon and needs more work.

Reported-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Link: https://lore.kernel.org/r/20231005081716.GA13853@pendragon.ideasonboard.com
Cc: Michael Grzeschik <m.grzeschik@pengutronix.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/gadget/function/uvc_video.c

index 97d875c27dcf9ab7a8e24b39ac2d75da982c60cf..c48c904f500fff8cab29f9bebecc26537cb2b3e9 100644 (file)
@@ -397,7 +397,7 @@ static void uvcg_video_pump(struct work_struct *work)
        bool buf_done;
        int ret;
 
-       if (video->ep->enabled && uvc->state == UVC_STATE_STREAMING) {
+       while (video->ep->enabled && uvc->state == UVC_STATE_STREAMING) {
                /*
                 * Retrieve the first available USB request, protected by the
                 * request lock.
@@ -409,11 +409,6 @@ static void uvcg_video_pump(struct work_struct *work)
                }
                req = list_first_entry(&video->req_free, struct usb_request,
                                        list);
-               if (!req) {
-                       spin_unlock_irqrestore(&video->req_lock, flags);
-                       return;
-               }
-
                list_del(&req->list);
                spin_unlock_irqrestore(&video->req_lock, flags);
 
@@ -442,7 +437,7 @@ static void uvcg_video_pump(struct work_struct *work)
                         * further.
                         */
                        spin_unlock_irqrestore(&queue->irqlock, flags);
-                       goto out;
+                       break;
                }
 
                /*
@@ -475,23 +470,20 @@ static void uvcg_video_pump(struct work_struct *work)
                /* Queue the USB request */
                ret = uvcg_video_ep_queue(video, req);
                spin_unlock_irqrestore(&queue->irqlock, flags);
+
                if (ret < 0) {
                        uvcg_queue_cancel(queue, 0);
-                       goto out;
+                       break;
                }
 
                /* Endpoint now owns the request */
                req = NULL;
                video->req_int_count++;
-       } else {
-               return;
        }
 
-       if (uvc->state == UVC_STATE_STREAMING)
-               queue_work(video->async_wq, &video->pump);
+       if (!req)
+               return;
 
-       return;
-out:
        spin_lock_irqsave(&video->req_lock, flags);
        list_add_tail(&req->list, &video->req_free);
        spin_unlock_irqrestore(&video->req_lock, flags);