]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
media: vb2: fix epoll() by calling poll_wait first
authorHans Verkuil <hverkuil-cisco@xs4all.nl>
Thu, 7 Feb 2019 11:49:43 +0000 (06:49 -0500)
committerMauro Carvalho Chehab <mchehab+samsung@kernel.org>
Mon, 18 Feb 2019 19:46:20 +0000 (14:46 -0500)
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-cisco@xs4all.nl>
Reported-by: Yi Qingliang <niqingliang2003@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
drivers/media/common/videobuf2/videobuf2-core.c
drivers/media/common/videobuf2/videobuf2-v4l2.c

index 275cddd8808cb7ce1fa11d2249a6ea07f5621bea..15b6b9c0a2e4aec1cc0e23fdfc6cd243b6ec1332 100644 (file)
@@ -2291,6 +2291,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.
         */
@@ -2342,8 +2344,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);
        }
 
        /*
index 55277370c3133655171bd78ce50b32216d1b4cb5..d09dee20e421a9ec4846acce8a0493dbd0a2cb8c 100644 (file)
@@ -868,16 +868,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);