* [PATCH] media: fix waitqueue_active without memory barrier in cpia2 driver
@ 2015-10-09 0:35 Kosuke Tatsukawa
0 siblings, 0 replies; only message in thread
From: Kosuke Tatsukawa @ 2015-10-09 0:35 UTC (permalink / raw)
To: Mauro Carvalho Chehab; +Cc: linux-media, linux-kernel
cpia2_usb_disconnect() seems to be missing a memory barrier which might
cause the waker to not notice the waiter and miss sending a wake_up as
in the following figure.
cpia2_usb_disconnect sync
------------------------------------------------------------------------
mutex_unlock(&cam->v4l2_lock);
if (waitqueue_active(&cam->wq_stream))
/* The CPU might reorder the test for
the waitqueue up here, before
prior writes complete */
/* wait_event_interruptible */
/* __wait_event_interruptible */
/* ___wait_event */
long __int = prepare_to_wait_event(
&wq, &__wait, state);
if (!cam->streaming ||
frame->status == FRAME_READY)
cam->curbuff->status = FRAME_READY;
cam->curbuff->length = 0;
schedule()
------------------------------------------------------------------------
The attached patch removes the call to waitqueue_active() leaving just
wake_up() behind. This fixes the problem because the call to
spin_lock_irqsave() in wake_up() will be an ACQUIRE operation.
I found this issue when I was looking through the linux source code
for places calling waitqueue_active() before wake_up*(), but without
preceding memory barriers, after sending a patch to fix a similar
issue in drivers/tty/n_tty.c (Details about the original issue can be
found here: https://lkml.org/lkml/2015/9/28/849).
Signed-off-by: Kosuke Tatsukawa <tatsu@ab.jp.nec.com>
---
drivers/media/usb/cpia2/cpia2_usb.c | 3 +--
1 files changed, 1 insertions(+), 2 deletions(-)
diff --git a/drivers/media/usb/cpia2/cpia2_usb.c b/drivers/media/usb/cpia2/cpia2_usb.c
index 351a78a..c1aa1ab 100644
--- a/drivers/media/usb/cpia2/cpia2_usb.c
+++ b/drivers/media/usb/cpia2/cpia2_usb.c
@@ -890,8 +890,7 @@ static void cpia2_usb_disconnect(struct usb_interface *intf)
DBG("Wakeup waiting processes\n");
cam->curbuff->status = FRAME_READY;
cam->curbuff->length = 0;
- if (waitqueue_active(&cam->wq_stream))
- wake_up_interruptible(&cam->wq_stream);
+ wake_up_interruptible(&cam->wq_stream);
}
DBG("Releasing interface\n");
--
1.7.1
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2015-10-09 0:36 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-10-09 0:35 [PATCH] media: fix waitqueue_active without memory barrier in cpia2 driver Kosuke Tatsukawa
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).