public inbox for igt-dev@lists.freedesktop.org
 help / color / mirror / Atom feed
From: Mika Kuoppala <mika.kuoppala@linux.intel.com>
To: igt-dev@lists.freedesktop.org
Cc: christoph.manszewski@intel.com,
	dominik.karol.piatkowski@intel.com, maciej.patelczyk@intel.com,
	jan.maslak@intel.com, zbigniew.kempczynski@intel.com,
	Mika Kuoppala <mika.kuoppala@linux.intel.com>
Subject: [PATCH i-g-t 02/21] lib/xe/xe_eudebug: Make sure debugger drains events
Date: Mon, 12 Jan 2026 14:59:48 +0200	[thread overview]
Message-ID: <20260112130008.1649357-3-mika.kuoppala@linux.intel.com> (raw)
In-Reply-To: <20260112130008.1649357-1-mika.kuoppala@linux.intel.com>

Do not exit from debugger worker until poll timeouts
as otherwise session can nuke the worker too early
and some events might get dropped.

Signed-off-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Reviewed-by: Christoph Manszewski <christoph.manszewski@intel.com>
---
 lib/xe/xe_eudebug.c             | 66 ++++++++++++++++++++++++---------
 lib/xe/xe_eudebug.h             |  7 ++--
 tests/intel/xe_eudebug_online.c |  4 +-
 3 files changed, 54 insertions(+), 23 deletions(-)

diff --git a/lib/xe/xe_eudebug.c b/lib/xe/xe_eudebug.c
index 0f09bc8a19..7c2c9505d1 100644
--- a/lib/xe/xe_eudebug.c
+++ b/lib/xe/xe_eudebug.c
@@ -1146,8 +1146,12 @@ static void *debugger_worker_loop(void *data)
 	sa.sa_flags |= SA_SIGINFO;
 	igt_assert_eq(sigaction(SIGTERM, &sa, NULL), 0);
 
+	WRITE_ONCE(d->worker_state, DEBUGGER_WORKER_RUNNING);
+
 	do {
 		p.fd = d->fd;
+		p.revents = 0;
+
 		ret = poll(&p, 1, timeout_ms);
 		if (d->received_sigint) {
 			d->handled_sigint = true;
@@ -1163,10 +1167,18 @@ static void *debugger_worker_loop(void *data)
 			}
 
 			igt_info("poll failed with errno %d\n", errno);
-			break;
+			goto out;
+		}
+
+		/* only exit after timeout to not miss events */
+		if (ret == 0 &&
+		    READ_ONCE(d->worker_state) != DEBUGGER_WORKER_RUNNING) {
+			igt_debug("debugger worker quitting with state %d\n",
+				  READ_ONCE(d->worker_state));
+			goto out;
 		}
 
-		if (ret == 1 && (p.revents & POLLIN)) {
+		if (ret == 1 && p.revents & POLLIN) {
 			int err = xe_eudebug_read_event(d->fd, e);
 
 			if (!err) {
@@ -1178,10 +1190,22 @@ static void *debugger_worker_loop(void *data)
 				igt_info("xe_eudebug_read_event returned %d\n", ret);
 			}
 		}
-	} while ((ret && READ_ONCE(d->worker_state) == DEBUGGER_WORKER_QUITTING) ||
-		 READ_ONCE(d->worker_state) == DEBUGGER_WORKER_ACTIVE);
 
-	d->worker_state = DEBUGGER_WORKER_INACTIVE;
+		if (ret == 1 && p.revents & POLLHUP) {
+			igt_info("debugger connection hangup\n");
+			goto out;
+		}
+
+		if (ret == 1 && p.revents & POLLNVAL) {
+			igt_info("debugger fd invalid\n");
+			goto out;
+		}
+	} while (1);
+
+out:
+	WRITE_ONCE(d->worker_state, DEBUGGER_WORKER_FINISHED);
+
+	igt_debug("debugger worker finished\n");
 
 	return NULL;
 }
@@ -1234,6 +1258,8 @@ xe_eudebug_debugger_create(int master_fd, uint64_t flags, void *data)
 	d->handled_sigint = false;
 	d->received_signal = false;
 
+	WRITE_ONCE(d->worker_state, DEBUGGER_WORKER_INIT);
+
 	return d;
 }
 
@@ -1254,7 +1280,7 @@ static void debugger_destroy_triggers(struct xe_eudebug_debugger *d)
  */
 void xe_eudebug_debugger_destroy(struct xe_eudebug_debugger *d)
 {
-	if (d->worker_state != DEBUGGER_WORKER_INACTIVE)
+	if (READ_ONCE(d->worker_state) != DEBUGGER_WORKER_FINISHED)
 		xe_eudebug_debugger_stop_worker(d);
 
 	if (d->target_pid)
@@ -1380,10 +1406,12 @@ void xe_eudebug_debugger_start_worker(struct xe_eudebug_debugger *d)
 {
 	int ret;
 
-	d->worker_state = DEBUGGER_WORKER_ACTIVE;
 	ret = pthread_create(&d->worker_thread, NULL, &debugger_worker_loop, d);
 
 	igt_assert_f(ret == 0, "Debugger worker thread creation failed!");
+
+	while(READ_ONCE(d->worker_state) != DEBUGGER_WORKER_RUNNING)
+		;
 }
 
 /**
@@ -1396,23 +1424,23 @@ void xe_eudebug_debugger_stop_worker(struct xe_eudebug_debugger *d)
 {
 	const int timeout_s = 3;
 	struct timespec t = {};
-	int ret;
-
-	igt_assert_neq(d->worker_state, DEBUGGER_WORKER_INACTIVE);
+	int ret = 0;
 
-	d->worker_state = DEBUGGER_WORKER_QUITTING; /* First time be polite. */
-	igt_assert_eq(clock_gettime(CLOCK_REALTIME, &t), 0);
-	t.tv_sec += timeout_s;
+	if (READ_ONCE(d->worker_state) == DEBUGGER_WORKER_RUNNING) {
+		/* First time be polite. */
+		WRITE_ONCE(d->worker_state, DEBUGGER_WORKER_SHOULD_QUIT);
+		igt_assert_eq(clock_gettime(CLOCK_REALTIME, &t), 0);
+		t.tv_sec += timeout_s;
 
-	ret = pthread_timedjoin_np(d->worker_thread, NULL, &t);
+		ret = pthread_timedjoin_np(d->worker_thread, NULL, &t);
+	}
 
 	if (ret == ETIMEDOUT) {
-		d->worker_state = DEBUGGER_WORKER_INACTIVE;
-		ret = pthread_join(d->worker_thread, NULL);
+		igt_info("DEBUGGER STATE %d FORCING\n", READ_ONCE(d->worker_state));
+		WRITE_ONCE(d->worker_state, DEBUGGER_WORKER_FINISHED);
 	}
 
-	igt_assert_f(ret == 0 || ret != ESRCH,
-		     "pthread join failed with error %d!\n", ret);
+	pthread_join(d->worker_thread, NULL);
 
 	event_log_sort(d->log);
 }
@@ -1720,6 +1748,8 @@ void xe_eudebug_session_run(struct xe_eudebug_session *s)
 
 	xe_eudebug_debugger_stop_worker(debugger);
 
+	xe_eudebug_client_stop(client);
+
 	xe_eudebug_event_log_print(debugger->log, true);
 	xe_eudebug_event_log_print(client->log, true);
 }
diff --git a/lib/xe/xe_eudebug.h b/lib/xe/xe_eudebug.h
index f1a2da4d84..ef9dacf0d2 100644
--- a/lib/xe/xe_eudebug.h
+++ b/lib/xe/xe_eudebug.h
@@ -20,9 +20,10 @@ struct xe_eudebug_event_log {
 };
 
 enum xe_eudebug_debugger_worker_state {
-	DEBUGGER_WORKER_INACTIVE = 0,
-	DEBUGGER_WORKER_ACTIVE,
-	DEBUGGER_WORKER_QUITTING,
+	DEBUGGER_WORKER_INIT = 0,
+	DEBUGGER_WORKER_RUNNING,
+	DEBUGGER_WORKER_SHOULD_QUIT,
+	DEBUGGER_WORKER_FINISHED,
 };
 
 struct xe_eudebug_debugger {
diff --git a/tests/intel/xe_eudebug_online.c b/tests/intel/xe_eudebug_online.c
index ff6c5ff19b..e59b99ee99 100644
--- a/tests/intel/xe_eudebug_online.c
+++ b/tests/intel/xe_eudebug_online.c
@@ -1690,8 +1690,8 @@ static void test_set_breakpoint_online_sigint_debugger(int fd,
 			usleep(1000);
 		close(s->debugger->fd);
 
-		igt_assert_eq(READ_ONCE(s->debugger->worker_state), DEBUGGER_WORKER_ACTIVE);
-		WRITE_ONCE(s->debugger->worker_state, DEBUGGER_WORKER_INACTIVE);
+		igt_assert_eq(READ_ONCE(s->debugger->worker_state), DEBUGGER_WORKER_RUNNING);
+		WRITE_ONCE(s->debugger->worker_state, DEBUGGER_WORKER_SHOULD_QUIT);
 
 		xe_eudebug_client_wait_done(s->client);
 
-- 
2.43.0


  parent reply	other threads:[~2026-01-12 13:00 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-01-12 12:59 [PATCH i-g-t 00/21] eudebug: uapi changes on connect and metadata Mika Kuoppala
2026-01-12 12:59 ` [PATCH i-g-t 01/21] lib/xe/xe_eudebug: Dont compare if everything filtered Mika Kuoppala
2026-01-12 12:59 ` Mika Kuoppala [this message]
2026-01-12 12:59 ` [PATCH i-g-t 03/21] lib/xe/xe_eudebug: Avoid matching if event is filtered Mika Kuoppala
2026-01-12 12:59 ` [PATCH i-g-t 04/21] tests/intel/xe_eudebug_sriov: Align expected return code Mika Kuoppala
2026-01-12 13:12   ` Piatkowski, Dominik Karol
2026-01-12 12:59 ` [PATCH i-g-t 05/21] eudebug: Remove metadata tests Mika Kuoppala
2026-01-12 12:59 ` [PATCH i-g-t 06/21] eudebug: Remove EVENT_OPEN and adjust tests Mika Kuoppala
2026-01-12 12:59 ` [PATCH i-g-t 07/21] tests/xe_eudebug: Adapt basic-read-event Mika Kuoppala
2026-01-12 12:59 ` [PATCH i-g-t 08/21] tests/intel/xe_eudebug: Fix connect-user test Mika Kuoppala
2026-01-12 12:59 ` [PATCH i-g-t 09/21] tests/intel/xe_eudebug: Mold ufence reconnect test to disconnect Mika Kuoppala
2026-01-12 12:59 ` [PATCH i-g-t 10/21] lib/xe_eudebug: Adapt to vm_bind debug data Mika Kuoppala
2026-01-12 12:59 ` [PATCH i-g-t 11/21] tests/xe_eudebug: Adapt basic-vm-bind and remove basic-vm-bind-extended Mika Kuoppala
2026-01-12 12:59 ` [PATCH i-g-t 12/21] tests/xe_eudebug: Adapt some ufence reliant tests to new vm_bind event interface Mika Kuoppala
2026-01-12 12:59 ` [PATCH i-g-t 13/21] tests/xe_eudebug: Adapt vm-bind-clear* subtests to debug data Mika Kuoppala
2026-01-12 13:00 ` [PATCH i-g-t 14/21] lib/xe_eudebug: Remove unused xe_eudebug_client_vm_bind wrappers Mika Kuoppala
2026-01-12 13:00 ` [PATCH i-g-t 15/21] tests/xe_eudebug: Add vm-bind-debug-data-ufence subtest Mika Kuoppala
2026-01-12 13:00 ` [PATCH i-g-t 16/21] lib/intel_batchbuffer: Add dummy OP_DEBUG_DATA operation to __xe_alloc_bind_ops Mika Kuoppala
2026-01-12 13:00 ` [PATCH i-g-t 17/21] tests/xe_eudebug_online: Adapt set-breakpoint test to work with new vm bind event interface Mika Kuoppala
2026-01-12 13:00 ` [PATCH i-g-t 18/21] tests/xe_eudebug_online: Adapt several subtests " Mika Kuoppala
2026-01-12 13:00 ` [PATCH i-g-t 19/21] lib/xe/xe_eudebug: Add callback for session work Mika Kuoppala
2026-01-12 13:00 ` [PATCH i-g-t 20/21] tests/intel/xe_eudebug: Add render node testing Mika Kuoppala
2026-01-12 13:00 ` [PATCH i-g-t 21/21] eudebug: Update xe_drm_eudebug.h uapi Mika Kuoppala

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260112130008.1649357-3-mika.kuoppala@linux.intel.com \
    --to=mika.kuoppala@linux.intel.com \
    --cc=christoph.manszewski@intel.com \
    --cc=dominik.karol.piatkowski@intel.com \
    --cc=igt-dev@lists.freedesktop.org \
    --cc=jan.maslak@intel.com \
    --cc=maciej.patelczyk@intel.com \
    --cc=zbigniew.kempczynski@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox