From dceb66a66c34a9022cfa11e4cfc03ae6e5f78dc6 Mon Sep 17 00:00:00 2001 From: Zbigniew Kempczyński Date: Fri, 20 Nov 2020 08:40:23 +0100 Subject: lib/intel_allocator: Separate allocator multiprocess start MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Reported-by: Andrzej Turko Cc: Andrzej Turko Cc: Dominik Grzegorzek Cc: Chris Wilson Acked-by: Daniel Vetter Acked-by: Petri Latvala --- lib/intel_allocator.c | 41 ++++++++++++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 7 deletions(-) (limited to 'lib/intel_allocator.c') diff --git a/lib/intel_allocator.c b/lib/intel_allocator.c index 466776bc..0b33b8b2 100644 --- a/lib/intel_allocator.c +++ b/lib/intel_allocator.c @@ -766,6 +766,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: * @@ -787,13 +819,8 @@ void intel_allocator_multiprocess_start(void) igt_assert_f(child_pid == -1, "Allocator thread can be spawned only in main IGT process\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(); } /** -- cgit v1.2.3