diff options
author | Michael Tretter <m.tretter@pengutronix.de> | 2019-06-27 08:44:32 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab+samsung@kernel.org> | 2019-07-23 08:44:45 -0400 |
commit | 8d86a15649957c182e90fa2b1267c16699bc12f1 (patch) | |
tree | 9297dbf656fd997caf5251b57326bdb3ba2e4eb4 | |
parent | 43266ad2b47db87b91f3198afa5ad61a4206c253 (diff) |
media: vb2: reorder checks in vb2_poll()
When reaching the end of stream, V4L2 clients may expect the
V4L2_EOS_EVENT before being able to dequeue the last buffer, which has
the V4L2_BUF_FLAG_LAST flag set.
If the vb2_poll() function first checks for events and afterwards if
buffers are available, a driver can queue the V4L2_EOS_EVENT event and
return the buffer after the check for events but before the check for
buffers. This causes vb2_poll() to signal that the buffer with
V4L2_BUF_FLAG_LAST can be read without the V4L2_EOS_EVENT being
available.
First, check for available buffers and afterwards for events to ensure
that if vb2_poll() signals POLLIN | POLLRDNORM for the
V4L2_BUF_FLAG_LAST buffer, it also signals POLLPRI for the
V4L2_EOS_EVENT.
Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
-rw-r--r-- | drivers/media/common/videobuf2/videobuf2-v4l2.c | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/drivers/media/common/videobuf2/videobuf2-v4l2.c b/drivers/media/common/videobuf2/videobuf2-v4l2.c index 40d76eb4c2fe..5a9ba3846f0a 100644 --- a/drivers/media/common/videobuf2/videobuf2-v4l2.c +++ b/drivers/media/common/videobuf2/videobuf2-v4l2.c | |||
@@ -872,17 +872,19 @@ EXPORT_SYMBOL_GPL(vb2_queue_release); | |||
872 | __poll_t vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait) | 872 | __poll_t vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait) |
873 | { | 873 | { |
874 | struct video_device *vfd = video_devdata(file); | 874 | struct video_device *vfd = video_devdata(file); |
875 | __poll_t res = 0; | 875 | __poll_t res; |
876 | |||
877 | res = vb2_core_poll(q, file, wait); | ||
876 | 878 | ||
877 | if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags)) { | 879 | if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags)) { |
878 | struct v4l2_fh *fh = file->private_data; | 880 | struct v4l2_fh *fh = file->private_data; |
879 | 881 | ||
880 | poll_wait(file, &fh->wait, wait); | 882 | poll_wait(file, &fh->wait, wait); |
881 | if (v4l2_event_pending(fh)) | 883 | if (v4l2_event_pending(fh)) |
882 | res = EPOLLPRI; | 884 | res |= EPOLLPRI; |
883 | } | 885 | } |
884 | 886 | ||
885 | return res | vb2_core_poll(q, file, wait); | 887 | return res; |
886 | } | 888 | } |
887 | EXPORT_SYMBOL_GPL(vb2_poll); | 889 | EXPORT_SYMBOL_GPL(vb2_poll); |
888 | 890 | ||