From: Hans Verkuil <hverkuil-ci...@xs4all.nl>

The epoll function expects that whenever the poll file op is
called, the poll_wait function is also called. That didn't
always happen in vb2_core_poll() and vb2_poll(). Fix this,
otherwise epoll() would timeout when it shouldn't.

Signed-off-by: Hans Verkuil <hverkuil-ci...@xs4all.nl>
Reported-by: Yi Qingliang <niqingliang2...@gmail.com>
---
 drivers/media/common/videobuf2/videobuf2-core.c | 4 ++--
 drivers/media/common/videobuf2/videobuf2-v4l2.c | 4 +---
 2 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/media/common/videobuf2/videobuf2-core.c 
b/drivers/media/common/videobuf2/videobuf2-core.c
index e07b6bdb6982..b40e9f48a943 100644
--- a/drivers/media/common/videobuf2/videobuf2-core.c
+++ b/drivers/media/common/videobuf2/videobuf2-core.c
@@ -2289,6 +2289,8 @@ __poll_t vb2_core_poll(struct vb2_queue *q, struct file 
*file,
        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.
         */
@@ -2340,8 +2342,6 @@ __poll_t vb2_core_poll(struct vb2_queue *q, struct file 
*file,
                 */
                if (q->last_buffer_dequeued)
                        return EPOLLIN | EPOLLRDNORM;
-
-               poll_wait(file, &q->done_wq, wait);
        }
 
        /*
diff --git a/drivers/media/common/videobuf2/videobuf2-v4l2.c 
b/drivers/media/common/videobuf2/videobuf2-v4l2.c
index 3aeaea3af42a..101479768f91 100644
--- a/drivers/media/common/videobuf2/videobuf2-v4l2.c
+++ b/drivers/media/common/videobuf2/videobuf2-v4l2.c
@@ -867,16 +867,14 @@ EXPORT_SYMBOL_GPL(vb2_queue_release);
 __poll_t vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait)
 {
        struct video_device *vfd = video_devdata(file);
-       __poll_t req_events = poll_requested_events(wait);
        __poll_t res = 0;
 
        if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags)) {
                struct v4l2_fh *fh = file->private_data;
 
+               poll_wait(file, &fh->wait, wait);
                if (v4l2_event_pending(fh))
                        res = EPOLLPRI;
-               else if (req_events & EPOLLPRI)
-                       poll_wait(file, &fh->wait, wait);
        }
 
        return res | vb2_core_poll(q, file, wait);
-- 
2.20.1

Reply via email to