From 048c700975c367d6612b9e70248046ee5233b699 Mon Sep 17 00:00:00 2001 From: Nicolas Benech Date: Mon, 13 Jan 2020 11:30:49 -0500 Subject: [PATCH] gpu: nvgpu: unit: exit properly if signal in single thread In the unit test framework, if a fatal error occurs in a module that generates a POSIX signal (like segfault), the error handler will log the error and kill the thread. However, if running in single threaded mode (which is the default), killing the thread means killing the process too. This means that results.json is not generated which makes results in automation more difficult to read. This patch updates the error handler to print the results as expected and exit gracefully. JIRA NVGPU-3157 Change-Id: I0204816b18312238e6502eb400e21d0e445e7e6c Signed-off-by: Nicolas Benech Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2278481 Reviewed-by: svc-mobile-coverity Reviewed-by: svc-mobile-cert Reviewed-by: Alex Waterman GVS: Gerrit_Virtual_Submit Reviewed-by: Vinod Gopalakrishnakurup Reviewed-by: mobile promotions Tested-by: mobile promotions --- userspace/src/exec.c | 37 ++++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/userspace/src/exec.c b/userspace/src/exec.c index 00fb60bb0..49f2d9308 100644 --- a/userspace/src/exec.c +++ b/userspace/src/exec.c @@ -138,6 +138,24 @@ thread_exit: return NULL; } +/* + * Go over all the modules and run them one by one. + */ +static void run_modules(struct unit_fw *fw) +{ + struct unit_module **modules; + + for (modules = fw->modules; *modules != NULL; modules++) { + if (fw->args->thread_count == 1) { + core_exec_module(*modules); + } else { + sem_wait(&unit_thread_semaphore); + pthread_create(&((*modules)->thread), NULL, + core_exec_module, (void *) *modules); + } + } +} + /* * According to POSIX, "Signals which are generated by some action attributable * to a particular thread, such as a hardware fault, shall be generated for the @@ -155,6 +173,15 @@ static void thread_error_handler(int sig, siginfo_t *siginfo, void *context) core_add_test_record(thread_local_module->fw, thread_local_module, thread_local_test, FAILED); sem_post(&unit_thread_semaphore); + + /* + * If single threaded, the signal will cause the process to end, so + * exit gracefully while printing test results. + */ + if (thread_local_module->fw->args->thread_count == 1) { + core_print_test_status(thread_local_module->fw); + exit(-1); + } pthread_exit(NULL); } @@ -228,15 +255,7 @@ int core_exec(struct unit_fw *fw) } } - for (modules = fw->modules; *modules != NULL; modules++) { - if (fw->args->thread_count == 1) { - core_exec_module(*modules); - } else { - sem_wait(&unit_thread_semaphore); - pthread_create(&((*modules)->thread), NULL, - core_exec_module, (void *) *modules); - } - } + run_modules(fw); if (fw->args->thread_count > 1) { for (modules = fw->modules; *modules != NULL; modules++) {