linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/2] media: always call poll_wait() on queues
@ 2020-11-23 15:18 Alexandre Courbot
  2020-11-23 15:18 ` [PATCH v2 1/2] media: videobuf2: " Alexandre Courbot
  2020-11-23 15:18 ` [PATCH v2 2/2] media: v4l2-mem2mem: " Alexandre Courbot
  0 siblings, 2 replies; 3+ messages in thread
From: Alexandre Courbot @ 2020-11-23 15:18 UTC (permalink / raw)
  To: Hans Verkuil, Tomasz Figa, Marek Szyprowski, Mauro Carvalho Chehab
  Cc: linux-media, linux-kernel, Alexandre Courbot

do_poll()/do_select() seem to set the _qproc member of poll_table to
NULL the first time they are called on a given table, making subsequent
calls of poll_wait() on that table no-ops. This behavior causes a bug
with the current poll implementations of vb2 and mem2mem, which only
call poll_wait() if a queue-related (EPOLLIN or EPOLLOUT) event if
present: if there is none during the first call (e.g. because userspace
only wanted to listen to EPOLLPRI), then EPOLLIN and EPOLLOUT will never
be signaled, event if they are requested later.

This can be fixed by making the call to poll_wait() unconditional, thus
making sure it will also be invoked during the first call.

The issue has been discussed in more detail on
https://www.spinics.net/lists/linux-media/msg179618.html.

Alexandre Courbot (2):
  media: videobuf2: always call poll_wait() on queues
  media: v4l2-mem2mem: always call poll_wait() on queues

 drivers/media/common/videobuf2/videobuf2-core.c | 11 +++++++++--
 drivers/media/v4l2-core/v4l2-mem2mem.c          | 15 ++++++++++++---
 2 files changed, 21 insertions(+), 5 deletions(-)

--
2.29.2


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH v2 1/2] media: videobuf2: always call poll_wait() on queues
  2020-11-23 15:18 [PATCH v2 0/2] media: always call poll_wait() on queues Alexandre Courbot
@ 2020-11-23 15:18 ` Alexandre Courbot
  2020-11-23 15:18 ` [PATCH v2 2/2] media: v4l2-mem2mem: " Alexandre Courbot
  1 sibling, 0 replies; 3+ messages in thread
From: Alexandre Courbot @ 2020-11-23 15:18 UTC (permalink / raw)
  To: Hans Verkuil, Tomasz Figa, Marek Szyprowski, Mauro Carvalho Chehab
  Cc: linux-media, linux-kernel, Alexandre Courbot

do_poll()/do_select() seem to set the _qproc member of poll_table to
NULL the first time they are called on a given table, making subsequent
calls of poll_wait() on that table no-ops. This is a problem for vb2
which calls poll_wait() on the V4L2 queues' waitqueues only when a
queue-related event is requested, which may not necessarily be the case
during the first poll.

Fix this by making the call to poll_wait() happen first thing and
unconditionally in vb2_core_poll().

Signed-off-by: Alexandre Courbot <gnurou@gmail.com>
---
 drivers/media/common/videobuf2/videobuf2-core.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/media/common/videobuf2/videobuf2-core.c b/drivers/media/common/videobuf2/videobuf2-core.c
index 4eab6d81cce1..ef06f90f5c6b 100644
--- a/drivers/media/common/videobuf2/videobuf2-core.c
+++ b/drivers/media/common/videobuf2/videobuf2-core.c
@@ -2363,13 +2363,20 @@ __poll_t vb2_core_poll(struct vb2_queue *q, struct file *file,
 	struct vb2_buffer *vb = NULL;
 	unsigned long flags;
 
+	/*
+	 * poll_wait() MUST be called on the first invocation on all the
+	 * potential queues of interest, even if we are not interested in their
+	 * events during this first call. Failure to do so will result in
+	 * queue's events to be ignored because the poll_table won't be capable
+	 * of adding new wait queues thereafter.
+	 */
+	poll_wait(file, &q->done_wq, wait);
+
 	if (!q->is_output && !(req_events & (EPOLLIN | EPOLLRDNORM)))
 		return 0;
 	if (q->is_output && !(req_events & (EPOLLOUT | EPOLLWRNORM)))
 		return 0;
 
-	poll_wait(file, &q->done_wq, wait);
-
 	/*
 	 * Start file I/O emulator only if streaming API has not been used yet.
 	 */
-- 
2.29.2


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH v2 2/2] media: v4l2-mem2mem: always call poll_wait() on queues
  2020-11-23 15:18 [PATCH v2 0/2] media: always call poll_wait() on queues Alexandre Courbot
  2020-11-23 15:18 ` [PATCH v2 1/2] media: videobuf2: " Alexandre Courbot
@ 2020-11-23 15:18 ` Alexandre Courbot
  1 sibling, 0 replies; 3+ messages in thread
From: Alexandre Courbot @ 2020-11-23 15:18 UTC (permalink / raw)
  To: Hans Verkuil, Tomasz Figa, Marek Szyprowski, Mauro Carvalho Chehab
  Cc: linux-media, linux-kernel, Alexandre Courbot

do_poll()/do_select() seem to set the _qproc member of poll_table to
NULL the first time they are called on a given table, making subsequent
calls of poll_wait() on that table no-ops. This is a problem for mem2mem
which calls poll_wait() on the V4L2 queues' waitqueues only when a
queue-related event is requested, which may not necessarily be the case
during the first poll.

For instance, a stateful decoder is typically only interested in
EPOLLPRI events when it starts, and will switch to listening to both
EPOLLPRI and EPOLLIN after receiving the initial resolution change event
and configuring the CAPTURE queue. However by the time that switch
happens and v4l2_m2m_poll_for_data() is called for the first time,
poll_wait() has become a no-op and the V4L2 queues waitqueues thus
cannot be registered.

Fix this by moving the registration to v4l2_m2m_poll() and do it whether
or not one of the queue-related events are requested.

Signed-off-by: Alexandre Courbot <gnurou@gmail.com>
---
 drivers/media/v4l2-core/v4l2-mem2mem.c | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c
index b221b4e438a1..e7f4bf5bc8dd 100644
--- a/drivers/media/v4l2-core/v4l2-mem2mem.c
+++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
@@ -887,9 +887,6 @@ static __poll_t v4l2_m2m_poll_for_data(struct file *file,
 	src_q = v4l2_m2m_get_src_vq(m2m_ctx);
 	dst_q = v4l2_m2m_get_dst_vq(m2m_ctx);
 
-	poll_wait(file, &src_q->done_wq, wait);
-	poll_wait(file, &dst_q->done_wq, wait);
-
 	/*
 	 * There has to be at least one buffer queued on each queued_list, which
 	 * means either in driver already or waiting for driver to claim it
@@ -922,9 +919,21 @@ __poll_t v4l2_m2m_poll(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
 		       struct poll_table_struct *wait)
 {
 	struct video_device *vfd = video_devdata(file);
+	struct vb2_queue *src_q = v4l2_m2m_get_src_vq(m2m_ctx);
+	struct vb2_queue *dst_q = v4l2_m2m_get_dst_vq(m2m_ctx);
 	__poll_t req_events = poll_requested_events(wait);
 	__poll_t rc = 0;
 
+	/*
+	 * poll_wait() MUST be called on the first invocation on all the
+	 * potential queues of interest, even if we are not interested in their
+	 * events during this first call. Failure to do so will result in
+	 * queue's events to be ignored because the poll_table won't be capable
+	 * of adding new wait queues thereafter.
+	 */
+	poll_wait(file, &src_q->done_wq, wait);
+	poll_wait(file, &dst_q->done_wq, wait);
+
 	if (req_events & (EPOLLOUT | EPOLLWRNORM | EPOLLIN | EPOLLRDNORM))
 		rc = v4l2_m2m_poll_for_data(file, m2m_ctx, wait);
 
-- 
2.29.2


^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2020-11-23 15:19 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-23 15:18 [PATCH v2 0/2] media: always call poll_wait() on queues Alexandre Courbot
2020-11-23 15:18 ` [PATCH v2 1/2] media: videobuf2: " Alexandre Courbot
2020-11-23 15:18 ` [PATCH v2 2/2] media: v4l2-mem2mem: " Alexandre Courbot

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).