All of lore.kernel.org
 help / color / mirror / Atom feed
* [igt-dev] [PATCH i-g-t] igt/drm_read: Exercise waking up the next waiter
@ 2019-02-27 10:20 Chris Wilson
  2019-02-27 10:45 ` [igt-dev] ✓ Fi.CI.BAT: success for " Patchwork
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Chris Wilson @ 2019-02-27 10:20 UTC (permalink / raw)
  To: igt-dev

Try to hit a bug in the kernel whereby a short reader does not wakeup
the next waiter (on the same fd) leading to forever blocking.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
---
 tests/drm_read.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 88 insertions(+)

diff --git a/tests/drm_read.c b/tests/drm_read.c
index 309f389f6..923a9f750 100644
--- a/tests/drm_read.c
+++ b/tests/drm_read.c
@@ -43,6 +43,7 @@
 #include <sys/ioctl.h>
 #include <sys/time.h>
 #include <sys/poll.h>
+#include <pthread.h>
 #include "drm.h"
 
 IGT_TEST_DESCRIPTION("Call read(drm) and see if it behaves.");
@@ -166,6 +167,90 @@ static void test_short_buffer(int in, int nonblock, enum pipe pipe)
 	teardown(fd);
 }
 
+struct short_buffer_wakeup {
+	pthread_mutex_t mutex;
+	pthread_cond_t send, recv;
+	int counter;
+	int done;
+	int fd;
+};
+
+static void *thread_short_buffer_wakeup(void *arg)
+{
+	struct short_buffer_wakeup *w = arg;
+	char buffer[1024]; /* events are typically 32 bytes */
+
+	while (!w->done) {
+		/* Short read, does not consume the event. */
+		igt_assert_eq(read(w->fd, buffer, 4), 0);
+
+		pthread_mutex_lock(&w->mutex);
+		if (!--w->counter)
+			pthread_cond_signal(&w->send);
+		pthread_cond_wait(&w->recv, &w->mutex);
+		pthread_mutex_unlock(&w->mutex);
+	}
+
+	return NULL;
+}
+
+static void test_short_buffer_wakeup(int in, enum pipe pipe)
+{
+	const int nt = sysconf(_SC_NPROCESSORS_ONLN) + 1;
+	struct short_buffer_wakeup w = {
+		.fd = setup(in, 0),
+	};
+	pthread_t t[nt];
+	char buffer[1024]; /* events are typically 32 bytes */
+
+	pthread_mutex_init(&w.mutex, NULL);
+	pthread_cond_init(&w.send, NULL);
+	pthread_cond_init(&w.recv, NULL);
+
+	for (int n = 0; n < nt; n++)
+		pthread_create(&t[n], NULL, thread_short_buffer_wakeup, &w);
+
+	igt_until_timeout(30) {
+		struct timespec tv;
+		int err = 0;
+
+		pthread_mutex_lock(&w.mutex);
+		w.counter = nt;
+		pthread_cond_broadcast(&w.recv);
+		pthread_mutex_unlock(&w.mutex);
+
+		/* Give each thread a chance to sleep in drm_read() */
+		pthread_yield();
+
+		/* One event should wake all threads as none consume */
+		generate_event(w.fd, pipe);
+
+		clock_gettime(CLOCK_REALTIME, &tv);
+		tv.tv_sec += 5; /* Let's be very generous to the scheduler */
+
+		pthread_mutex_lock(&w.mutex);
+		while (w.counter && !err)
+			err = pthread_cond_timedwait(&w.send, &w.mutex, &tv);
+		pthread_mutex_unlock(&w.mutex);
+
+		igt_assert_f(err == 0,
+			     "Timed out waiting for drm_read() to wakeup on an event\n");
+
+
+		/* No thread should consume the event */
+		igt_assert(read(w.fd, buffer, 40) > 0);
+	}
+	pthread_mutex_lock(&w.mutex);
+	w.done = true;
+	pthread_cond_broadcast(&w.recv);
+	pthread_mutex_unlock(&w.mutex);
+
+	for (int n = 0; n < nt; n++)
+		pthread_join(t[n], NULL);
+
+	close(w.fd);
+}
+
 igt_main
 {
 	int fd;
@@ -218,4 +303,7 @@ igt_main
 
 	igt_subtest("short-buffer-nonblock")
 		test_short_buffer(fd, 1, pipe);
+
+	igt_subtest("short-buffer-wakeup")
+		test_short_buffer_wakeup(fd, pipe);
 }
-- 
2.20.1

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply related	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2019-02-27 21:47 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-02-27 10:20 [igt-dev] [PATCH i-g-t] igt/drm_read: Exercise waking up the next waiter Chris Wilson
2019-02-27 10:45 ` [igt-dev] ✓ Fi.CI.BAT: success for " Patchwork
2019-02-27 11:48 ` [igt-dev] ✓ Fi.CI.IGT: " Patchwork
2019-02-27 11:50   ` Chris Wilson
2019-02-27 21:18   ` Antonio Argenziano
2019-02-27 21:22     ` Chris Wilson
2019-02-27 21:47       ` Antonio Argenziano
2019-02-27 20:46 ` [igt-dev] [PATCH i-g-t] " Ville Syrjälä
2019-02-27 21:13   ` Chris Wilson

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.