Commit dd8695e4 authored by Hans Verkuil's avatar Hans Verkuil Committed by Mauro Carvalho Chehab

media: v4l2-mem2mem: fix epoll() by calling poll_wait first

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 v4l2_m2m_poll(). Fix this, otherwise
epoll() would timeout when it shouldn't.
Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+samsung@kernel.org>
parent 398d7680
...@@ -617,20 +617,22 @@ __poll_t v4l2_m2m_poll(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, ...@@ -617,20 +617,22 @@ __poll_t v4l2_m2m_poll(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
__poll_t rc = 0; __poll_t rc = 0;
unsigned long flags; unsigned long flags;
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);
if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags)) { if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags)) {
struct v4l2_fh *fh = file->private_data; struct v4l2_fh *fh = file->private_data;
poll_wait(file, &fh->wait, wait);
if (v4l2_event_pending(fh)) if (v4l2_event_pending(fh))
rc = EPOLLPRI; rc = EPOLLPRI;
else if (req_events & EPOLLPRI)
poll_wait(file, &fh->wait, wait);
if (!(req_events & (EPOLLOUT | EPOLLWRNORM | EPOLLIN | EPOLLRDNORM))) if (!(req_events & (EPOLLOUT | EPOLLWRNORM | EPOLLIN | EPOLLRDNORM)))
return rc; return rc;
} }
src_q = v4l2_m2m_get_src_vq(m2m_ctx);
dst_q = v4l2_m2m_get_dst_vq(m2m_ctx);
/* /*
* There has to be at least one buffer queued on each queued_list, which * 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 * means either in driver already or waiting for driver to claim it
...@@ -642,11 +644,6 @@ __poll_t v4l2_m2m_poll(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, ...@@ -642,11 +644,6 @@ __poll_t v4l2_m2m_poll(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
goto end; goto end;
} }
spin_lock_irqsave(&src_q->done_lock, flags);
if (list_empty(&src_q->done_list))
poll_wait(file, &src_q->done_wq, wait);
spin_unlock_irqrestore(&src_q->done_lock, flags);
spin_lock_irqsave(&dst_q->done_lock, flags); spin_lock_irqsave(&dst_q->done_lock, flags);
if (list_empty(&dst_q->done_list)) { if (list_empty(&dst_q->done_list)) {
/* /*
...@@ -657,8 +654,6 @@ __poll_t v4l2_m2m_poll(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, ...@@ -657,8 +654,6 @@ __poll_t v4l2_m2m_poll(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
spin_unlock_irqrestore(&dst_q->done_lock, flags); spin_unlock_irqrestore(&dst_q->done_lock, flags);
return rc | EPOLLIN | EPOLLRDNORM; return rc | EPOLLIN | EPOLLRDNORM;
} }
poll_wait(file, &dst_q->done_wq, wait);
} }
spin_unlock_irqrestore(&dst_q->done_lock, flags); spin_unlock_irqrestore(&dst_q->done_lock, flags);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment