Thread (34 messages) 34 messages, 2 authors, 2021-01-15

[igt-dev] [PATCH i-g-t v16 07/31] lib/intel_allocator: Try to stop smoothly instead of deinit

From: Zbigniew Kempczyński <hidden>
Date: 2021-01-15 12:09:00
Subsystem: library code, the rest · Maintainers: Andrew Morton, Linus Torvalds

Avoid race when stop was send to allocator thread. We wait around
100 ms to give thread chance to stop smoothly instead of removing
queue and enforcing exiting all blocked message syscalls.

Signed-off-by: Zbigniew Kempczyński <redacted>
Cc: Dominik Grzegorzek <redacted>
Cc: Chris Wilson <redacted>
---
 lib/intel_allocator.c | 26 +++++++++++++++++++++++---
 1 file changed, 23 insertions(+), 3 deletions(-)
diff --git a/lib/intel_allocator.c b/lib/intel_allocator.c
index 588d9cffc..7085fc168 100644
--- a/lib/intel_allocator.c
+++ b/lib/intel_allocator.c
@@ -70,6 +70,7 @@ static struct igt_map *allocators_map;
 static pthread_mutex_t map_mutex = PTHREAD_MUTEX_INITIALIZER;
 static bool multiprocess;
 static pthread_t allocator_thread;
+static bool allocator_thread_running;
 
 static bool warn_if_not_empty;
 
@@ -467,6 +468,8 @@ static void *allocator_thread_loop(void *data)
 		   (long) allocator_pid, (long) gettid());
 	alloc_info("Entering allocator loop\n");
 
+	WRITE_ONCE(allocator_thread_running, true);
+
 	while (1) {
 		ret = recv_req(channel, &req);
 
@@ -500,6 +503,8 @@ static void *allocator_thread_loop(void *data)
 		}
 	}
 
+	WRITE_ONCE(allocator_thread_running, false);
+
 	return NULL;
 }
 
@@ -537,15 +542,30 @@ void intel_allocator_multiprocess_start(void)
  * Function turns off intel_allocator multiprocess mode what means means
  * stopping allocator thread and deinitializing its data.
  */
+#define STOP_TIMEOUT_MS 100
 void intel_allocator_multiprocess_stop(void)
 {
+	int time_left = STOP_TIMEOUT_MS;
+
 	alloc_info("allocator multiprocess stop\n");
 
 	if (multiprocess) {
 		send_alloc_stop(channel);
-		/* Deinit, this should stop all blocked syscalls, if any */
-		channel->deinit(channel);
-		pthread_join(allocator_thread, NULL);
+
+		/* We prefer joining thread when it is stopped */
+		while (time_left-- > 0 && READ_ONCE(allocator_thread_running))
+			usleep(1000); /* coarse calculation */
+
+		/* Thread has stuck somewhere */
+		if (READ_ONCE(allocator_thread_running)) {
+			/* Deinit, this should stop all blocked syscalls, if any */
+			channel->deinit(channel);
+			pthread_join(allocator_thread, NULL);
+		} else {
+			pthread_join(allocator_thread, NULL);
+			channel->deinit(channel);
+		}
+
 		/* But we're not sure does child will stuck */
 		kill_children(SIGINT);
 		igt_waitchildren_timeout(5, "Stopping children");
-- 
2.26.0

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help