[igt-dev] [PATCH i-g-t v18 30/31] lib/intel_allocator: Separate allocator multiprocess start

Zbigniew Kempczyński zbigniew.kempczynski at intel.com
Fri Jan 29 14:44:53 UTC 2021


Validating allocator code (leaks and memory overwriting) can be done
with address sanitizer. When allocator is not working in multiprocess
mode it is easy, problems start when fork is in the game. In this
situation we need to separate preparation and starting allocator thread.

Signed-off-by: Zbigniew Kempczyński <zbigniew.kempczynski at intel.com>
Reported-by: Andrzej Turko <andrzej.turko at linux.intel.com>
Cc: Andrzej Turko <andrzej.turko at linux.intel.com>
Cc: Dominik Grzegorzek <dominik.grzegorzek at intel.com>
Cc: Chris Wilson <chris at chris-wilson.co.uk>
---
 lib/intel_allocator.c | 41 ++++++++++++++++++++++++++++++++++-------
 lib/intel_allocator.h |  2 ++
 2 files changed, 36 insertions(+), 7 deletions(-)

diff --git a/lib/intel_allocator.c b/lib/intel_allocator.c
index 37bd9e516..364b52abd 100644
--- a/lib/intel_allocator.c
+++ b/lib/intel_allocator.c
@@ -489,6 +489,38 @@ static void *allocator_thread_loop(void *data)
 	return NULL;
 }
 
+
+/**
+ * __intel_allocator_multiprocess_prepare:
+ *
+ * Prepares allocator infrastructure to work in multiprocess mode.
+ *
+ * Some description is required why prepare/start steps are separated.
+ * When we write the code and we don't use address sanitizer simple
+ * intel_allocator_multiprocess_start() call is enough. With address
+ * sanitizer and using forking we can encounter situation where one
+ * forked child called allocator alloc() (so parent has some poisoned
+ * memory in shadow map), then second fork occurs. Second child will
+ * get poisoned shadow map from parent (there allocator thread reside).
+ * Checking shadow map in this child will report memory leak.
+ *
+ * How to separate initialization steps take a look into api_intel_allocator.c
+ * fork_simple_stress() function.
+ */
+void __intel_allocator_multiprocess_prepare(void)
+{
+	intel_allocator_init();
+
+	multiprocess = true;
+	channel->init(channel);
+}
+
+void __intel_allocator_multiprocess_start(void)
+{
+	pthread_create(&allocator_thread, NULL,
+		       allocator_thread_loop, NULL);
+}
+
 /**
  * intel_allocator_multiprocess_start:
  *
@@ -508,13 +540,8 @@ void intel_allocator_multiprocess_start(void)
 {
 	alloc_info("allocator multiprocess start\n");
 
-	intel_allocator_init();
-
-	multiprocess = true;
-	channel->init(channel);
-
-	pthread_create(&allocator_thread, NULL,
-		       allocator_thread_loop, NULL);
+	__intel_allocator_multiprocess_prepare();
+	__intel_allocator_multiprocess_start();
 }
 
 /**
diff --git a/lib/intel_allocator.h b/lib/intel_allocator.h
index 49043fbbc..e39ed0285 100644
--- a/lib/intel_allocator.h
+++ b/lib/intel_allocator.h
@@ -102,6 +102,8 @@ struct intel_allocator {
 };
 
 void intel_allocator_init(void);
+void __intel_allocator_multiprocess_prepare(void);
+void __intel_allocator_multiprocess_start(void);
 void intel_allocator_multiprocess_start(void);
 void intel_allocator_multiprocess_stop(void);
 
-- 
2.26.0



More information about the igt-dev mailing list