aboutsummaryrefslogtreecommitdiffstats
path: root/utils/v4l2-compliance
diff options
context:
space:
mode:
authorAlexandre Courbot <gnurou@gmail.com>2020-11-24 00:18:56 +0900
committerHans Verkuil <hverkuil-cisco@xs4all.nl>2021-01-06 09:20:33 +0100
commitc83b0bda1f82947687e8b8645b78f6d2b7e7fcee (patch)
tree217cb21451f23546cb328b0ef49f3b9bb53120bc /utils/v4l2-compliance
parente0e4114f971407acfdf1e8173c86e2e08fa01077 (diff)
v4l2-compliance: test for vb2/m2m poll kernel bug
A bug has been discovered in the vb2 and m2m implementations of poll where EPOLLIN and EPOLLOUT events are never signaled to epoll_wait() unless at least one of them is included in the initial epoll_ctl() call. The presence of this bug can be detected by setting an initial empty set of events with EPOLL_CTL_ADD, then setting the events we are interested in using EPOLL_CTL_MOD. epoll_wait() will then invariably timeout even if there is a queue-related event pending. Signed-off-by: Alexandre Courbot <gnurou@gmail.com> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Diffstat (limited to 'utils/v4l2-compliance')
-rw-r--r--utils/v4l2-compliance/v4l2-test-buffers.cpp17
1 files changed, 16 insertions, 1 deletions
diff --git a/utils/v4l2-compliance/v4l2-test-buffers.cpp b/utils/v4l2-compliance/v4l2-test-buffers.cpp
index 8000db23..291019c7 100644
--- a/utils/v4l2-compliance/v4l2-test-buffers.cpp
+++ b/utils/v4l2-compliance/v4l2-test-buffers.cpp
@@ -903,6 +903,17 @@ static int captureBufs(struct node *node, struct node *node_m2m_cap, const cv4l_
epollfd = epoll_create1(0);
fail_on_test(epollfd < 0);
+
+ /*
+ * Many older versions of the vb2 and m2m have a bug where
+ * EPOLLIN and EPOLLOUT events are never signaled unless they
+ * are part of the initial EPOLL_CTL_ADD. We set an initial
+ * empty set of events, which we then modify with EPOLL_CTL_MOD,
+ * in order to detect that condition.
+ */
+ ev.events = 0;
+ fail_on_test(epoll_ctl(epollfd, EPOLL_CTL_ADD, node->g_fd(), &ev));
+
if (node->is_m2m)
ev.events = EPOLLIN | EPOLLOUT | EPOLLPRI;
else if (v4l_type_is_output(q.g_type()))
@@ -910,7 +921,7 @@ static int captureBufs(struct node *node, struct node *node_m2m_cap, const cv4l_
else
ev.events = EPOLLIN;
ev.data.fd = node->g_fd();
- fail_on_test(epoll_ctl(epollfd, EPOLL_CTL_ADD, node->g_fd(), &ev));
+ fail_on_test(epoll_ctl(epollfd, EPOLL_CTL_MOD, node->g_fd(), &ev));
}
if (pollmode)
@@ -944,6 +955,10 @@ static int captureBufs(struct node *node, struct node *node_m2m_cap, const cv4l_
can_read = FD_ISSET(node->g_fd(), &rfds);
have_event = FD_ISSET(node->g_fd(), &efds);
} else if (pollmode == POLL_MODE_EPOLL) {
+ /*
+ * This can fail with a timeout on older kernels for
+ * drivers using vb2_core_poll() v4l2_m2m_poll().
+ */
ret = epoll_wait(epollfd, &ev, 1, 2000);
fail_on_test(ret == 0);
fail_on_test(ret < 0);

Privacy Policy