]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
drop queue-4.19/media-uvcvideo-fix-race-condition-with-usb_kill_urb.patch
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 10 Mar 2023 12:14:50 +0000 (13:14 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 10 Mar 2023 12:14:50 +0000 (13:14 +0100)
queue-4.19/media-uvcvideo-fix-race-condition-with-usb_kill_urb.patch [deleted file]
queue-4.19/series

diff --git a/queue-4.19/media-uvcvideo-fix-race-condition-with-usb_kill_urb.patch b/queue-4.19/media-uvcvideo-fix-race-condition-with-usb_kill_urb.patch
deleted file mode 100644 (file)
index c33d512..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-From 619d9b710cf06f7a00a17120ca92333684ac45a8 Mon Sep 17 00:00:00 2001
-From: Ricardo Ribalda <ribalda@chromium.org>
-Date: Thu, 5 Jan 2023 15:31:29 +0100
-Subject: media: uvcvideo: Fix race condition with usb_kill_urb
-
-From: Ricardo Ribalda <ribalda@chromium.org>
-
-commit 619d9b710cf06f7a00a17120ca92333684ac45a8 upstream.
-
-usb_kill_urb warranties that all the handlers are finished when it
-returns, but does not protect against threads that might be handling
-asynchronously the urb.
-
-For UVC, the function uvc_ctrl_status_event_async() takes care of
-control changes asynchronously.
-
-If the code is executed in the following order:
-
-CPU 0                                  CPU 1
-=====                                  =====
-uvc_status_complete()
-                                       uvc_status_stop()
-uvc_ctrl_status_event_work()
-                                       uvc_status_start() -> FAIL
-
-Then uvc_status_start will keep failing and this error will be shown:
-
-<4>[    5.540139] URB 0000000000000000 submitted while active
-drivers/usb/core/urb.c:378 usb_submit_urb+0x4c3/0x528
-
-Let's improve the current situation, by not re-submiting the urb if
-we are stopping the status event. Also process the queued work
-(if any) during stop.
-
-CPU 0                                  CPU 1
-=====                                  =====
-uvc_status_complete()
-                                       uvc_status_stop()
-                                       uvc_status_start()
-uvc_ctrl_status_event_work() -> FAIL
-
-Hopefully, with the usb layer protection this should be enough to cover
-all the cases.
-
-Cc: stable@vger.kernel.org
-Fixes: e5225c820c05 ("media: uvcvideo: Send a control event when a Control Change interrupt arrives")
-Reviewed-by: Yunke Cao <yunkec@chromium.org>
-Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
-Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
-Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/media/usb/uvc/uvc_ctrl.c   |    5 +++++
- drivers/media/usb/uvc/uvc_status.c |   37 +++++++++++++++++++++++++++++++++++++
- drivers/media/usb/uvc/uvcvideo.h   |    1 +
- 3 files changed, 43 insertions(+)
-
---- a/drivers/media/usb/uvc/uvc_ctrl.c
-+++ b/drivers/media/usb/uvc/uvc_ctrl.c
-@@ -11,6 +11,7 @@
-  *
-  */
-+#include <asm/barrier.h>
- #include <linux/kernel.h>
- #include <linux/list.h>
- #include <linux/module.h>
-@@ -1318,6 +1319,10 @@ static void uvc_ctrl_status_event_work(s
-       mutex_unlock(&chain->ctrl_mutex);
-+      /* The barrier is needed to synchronize with uvc_status_stop(). */
-+      if (smp_load_acquire(&dev->flush_status))
-+              return;
-+
-       /* Resubmit the URB. */
-       w->urb->interval = dev->int_ep->desc.bInterval;
-       ret = usb_submit_urb(w->urb, GFP_KERNEL);
---- a/drivers/media/usb/uvc/uvc_status.c
-+++ b/drivers/media/usb/uvc/uvc_status.c
-@@ -11,6 +11,7 @@
-  *
-  */
-+#include <asm/barrier.h>
- #include <linux/kernel.h>
- #include <linux/input.h>
- #include <linux/slab.h>
-@@ -314,5 +315,41 @@ int uvc_status_start(struct uvc_device *
- void uvc_status_stop(struct uvc_device *dev)
- {
-+      struct uvc_ctrl_work *w = &dev->async_ctrl;
-+
-+      /*
-+       * Prevent the asynchronous control handler from requeing the URB. The
-+       * barrier is needed so the flush_status change is visible to other
-+       * CPUs running the asynchronous handler before usb_kill_urb() is
-+       * called below.
-+       */
-+      smp_store_release(&dev->flush_status, true);
-+
-+      /*
-+       * Cancel any pending asynchronous work. If any status event was queued,
-+       * process it synchronously.
-+       */
-+      if (cancel_work_sync(&w->work))
-+              uvc_ctrl_status_event(w->chain, w->ctrl, w->data);
-+
-+      /* Kill the urb. */
-       usb_kill_urb(dev->int_urb);
-+
-+      /*
-+       * The URB completion handler may have queued asynchronous work. This
-+       * won't resubmit the URB as flush_status is set, but it needs to be
-+       * cancelled before returning or it could then race with a future
-+       * uvc_status_start() call.
-+       */
-+      if (cancel_work_sync(&w->work))
-+              uvc_ctrl_status_event(w->chain, w->ctrl, w->data);
-+
-+      /*
-+       * From this point, there are no events on the queue and the status URB
-+       * is dead. No events will be queued until uvc_status_start() is called.
-+       * The barrier is needed to make sure that flush_status is visible to
-+       * uvc_ctrl_status_event_work() when uvc_status_start() will be called
-+       * again.
-+       */
-+      smp_store_release(&dev->flush_status, false);
- }
---- a/drivers/media/usb/uvc/uvcvideo.h
-+++ b/drivers/media/usb/uvc/uvcvideo.h
-@@ -603,6 +603,7 @@ struct uvc_device {
-       /* Status Interrupt Endpoint */
-       struct usb_host_endpoint *int_ep;
-       struct urb *int_urb;
-+      bool flush_status;
-       u8 *status;
-       struct input_dev *input;
-       char input_phys[64];
index f0a3f72e6099c3234524ed4c1287de49b79bfd8a..6a1ad2b6bb486f70b12fa6490945cf0fea149471 100644 (file)
@@ -245,5 +245,4 @@ phy-rockchip-typec-fix-unsigned-comparison-with-less.patch
 bluetooth-hci_sock-purge-socket-queues-in-the-destruct-callback.patch
 s390-maccess-add-no-dat-mode-to-kernel_write.patch
 s390-setup-init-jump-labels-before-command-line-parsing.patch
-media-uvcvideo-fix-race-condition-with-usb_kill_urb.patch
 tcp-fix-listen-regression-in-5.15.88.patch