]> git.itanic.dy.fi Git - linux-stable/commitdiff
selftests/resctrl: Extend signal handler coverage to unmount on receiving signal
authorIlpo Järvinen <ilpo.jarvinen@linux.intel.com>
Mon, 2 Oct 2023 09:48:08 +0000 (12:48 +0300)
committerShuah Khan <skhan@linuxfoundation.org>
Fri, 13 Oct 2023 20:54:09 +0000 (14:54 -0600)
Unmounting resctrl FS has been moved into the per test functions in
resctrl_tests.c by commit caddc0fbe495 ("selftests/resctrl: Move
resctrl FS mount/umount to higher level"). In case a signal (SIGINT,
SIGTERM, or SIGHUP) is received, the running selftest is aborted by
ctrlc_handler() which then unmounts resctrl fs before exiting. The
current section between signal_handler_register() and
signal_handler_unregister(), however, does not cover the entire
duration when resctrl FS is mounted.

Move signal_handler_register() and signal_handler_unregister() calls
from per test files into resctrl_tests.c to properly unmount resctrl
fs. In order to not add signal_handler_register()/unregister() n times,
create helpers test_prepare() and test_cleanup().

Do not call ksft_exit_fail_msg() in test_prepare() but only in the per
test function to keep the control flow cleaner without adding calls to
exit() deep into the call chain.

Adjust child process kill() call in ctrlc_handler() to only be invoked
if the child was already forked.

Fixes: caddc0fbe495 ("selftests/resctrl: Move resctrl FS mount/umount to higher level")
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Tested-by: Shaopeng Tan <tan.shaopeng@jp.fujitsu.com>
Reviewed-by: Shaopeng Tan <tan.shaopeng@jp.fujitsu.com>
Reviewed-by: Reinette Chatre <reinette.chatre@intel.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
tools/testing/selftests/resctrl/cat_test.c
tools/testing/selftests/resctrl/resctrl_tests.c
tools/testing/selftests/resctrl/resctrl_val.c

index 97b87285ab2a9494d6c26a623faeb079f04ea665..224ba8544d8afc88910b01e77e77a35c8e2cfdc2 100644 (file)
@@ -167,12 +167,6 @@ int cat_perf_miss_val(int cpu_no, int n, char *cache_type)
                strcpy(param.filename, RESULT_FILE_NAME1);
                param.num_of_runs = 0;
                param.cpu_no = sibling_cpu_no;
-       } else {
-               ret = signal_handler_register();
-               if (ret) {
-                       kill(bm_pid, SIGKILL);
-                       goto out;
-               }
        }
 
        remove(param.filename);
@@ -209,10 +203,8 @@ int cat_perf_miss_val(int cpu_no, int n, char *cache_type)
                }
                close(pipefd[0]);
                kill(bm_pid, SIGKILL);
-               signal_handler_unregister();
        }
 
-out:
        cat_test_cleanup();
 
        return ret;
index 823672a20a439d576a63377428f72dc7d9bf3c4a..495aeee5b734406feb0d33abe0e7ebb6e323be00 100644 (file)
@@ -67,21 +67,45 @@ void tests_cleanup(void)
        cat_test_cleanup();
 }
 
-static void run_mbm_test(const char * const *benchmark_cmd, int cpu_no)
+static int test_prepare(void)
 {
        int res;
 
-       ksft_print_msg("Starting MBM BW change ...\n");
+       res = signal_handler_register();
+       if (res) {
+               ksft_print_msg("Failed to register signal handler\n");
+               return res;
+       }
 
        res = mount_resctrlfs();
        if (res) {
-               ksft_exit_fail_msg("Failed to mount resctrl FS\n");
+               signal_handler_unregister();
+               ksft_print_msg("Failed to mount resctrl FS\n");
+               return res;
+       }
+       return 0;
+}
+
+static void test_cleanup(void)
+{
+       umount_resctrlfs();
+       signal_handler_unregister();
+}
+
+static void run_mbm_test(const char * const *benchmark_cmd, int cpu_no)
+{
+       int res;
+
+       ksft_print_msg("Starting MBM BW change ...\n");
+
+       if (test_prepare()) {
+               ksft_exit_fail_msg("Abnormal failure when preparing for the test\n");
                return;
        }
 
        if (!validate_resctrl_feature_request(MBM_STR) || (get_vendor() != ARCH_INTEL)) {
                ksft_test_result_skip("Hardware does not support MBM or MBM is disabled\n");
-               goto umount;
+               goto cleanup;
        }
 
        res = mbm_bw_change(cpu_no, benchmark_cmd);
@@ -89,8 +113,8 @@ static void run_mbm_test(const char * const *benchmark_cmd, int cpu_no)
        if ((get_vendor() == ARCH_INTEL) && res)
                ksft_print_msg("Intel MBM may be inaccurate when Sub-NUMA Clustering is enabled. Check BIOS configuration.\n");
 
-umount:
-       umount_resctrlfs();
+cleanup:
+       test_cleanup();
 }
 
 static void run_mba_test(const char * const *benchmark_cmd, int cpu_no)
@@ -99,22 +123,21 @@ static void run_mba_test(const char * const *benchmark_cmd, int cpu_no)
 
        ksft_print_msg("Starting MBA Schemata change ...\n");
 
-       res = mount_resctrlfs();
-       if (res) {
-               ksft_exit_fail_msg("Failed to mount resctrl FS\n");
+       if (test_prepare()) {
+               ksft_exit_fail_msg("Abnormal failure when preparing for the test\n");
                return;
        }
 
        if (!validate_resctrl_feature_request(MBA_STR) || (get_vendor() != ARCH_INTEL)) {
                ksft_test_result_skip("Hardware does not support MBA or MBA is disabled\n");
-               goto umount;
+               goto cleanup;
        }
 
        res = mba_schemata_change(cpu_no, benchmark_cmd);
        ksft_test_result(!res, "MBA: schemata change\n");
 
-umount:
-       umount_resctrlfs();
+cleanup:
+       test_cleanup();
 }
 
 static void run_cmt_test(const char * const *benchmark_cmd, int cpu_no)
@@ -123,15 +146,14 @@ static void run_cmt_test(const char * const *benchmark_cmd, int cpu_no)
 
        ksft_print_msg("Starting CMT test ...\n");
 
-       res = mount_resctrlfs();
-       if (res) {
-               ksft_exit_fail_msg("Failed to mount resctrl FS\n");
+       if (test_prepare()) {
+               ksft_exit_fail_msg("Abnormal failure when preparing for the test\n");
                return;
        }
 
        if (!validate_resctrl_feature_request(CMT_STR)) {
                ksft_test_result_skip("Hardware does not support CMT or CMT is disabled\n");
-               goto umount;
+               goto cleanup;
        }
 
        res = cmt_resctrl_val(cpu_no, 5, benchmark_cmd);
@@ -139,8 +161,8 @@ static void run_cmt_test(const char * const *benchmark_cmd, int cpu_no)
        if ((get_vendor() == ARCH_INTEL) && res)
                ksft_print_msg("Intel CMT may be inaccurate when Sub-NUMA Clustering is enabled. Check BIOS configuration.\n");
 
-umount:
-       umount_resctrlfs();
+cleanup:
+       test_cleanup();
 }
 
 static void run_cat_test(int cpu_no, int no_of_bits)
@@ -149,22 +171,21 @@ static void run_cat_test(int cpu_no, int no_of_bits)
 
        ksft_print_msg("Starting CAT test ...\n");
 
-       res = mount_resctrlfs();
-       if (res) {
-               ksft_exit_fail_msg("Failed to mount resctrl FS\n");
+       if (test_prepare()) {
+               ksft_exit_fail_msg("Abnormal failure when preparing for the test\n");
                return;
        }
 
        if (!validate_resctrl_feature_request(CAT_STR)) {
                ksft_test_result_skip("Hardware does not support CAT or CAT is disabled\n");
-               goto umount;
+               goto cleanup;
        }
 
        res = cat_perf_miss_val(cpu_no, no_of_bits, "L3");
        ksft_test_result(!res, "CAT: test\n");
 
-umount:
-       umount_resctrlfs();
+cleanup:
+       test_cleanup();
 }
 
 int main(int argc, char **argv)
index 01bbe11a89834a66bb9410cbbe619273c50d8ef1..b8ca6fa40b3bf7cf3c55871794b14d4257b425b6 100644 (file)
@@ -468,7 +468,9 @@ pid_t bm_pid, ppid;
 
 void ctrlc_handler(int signum, siginfo_t *info, void *ptr)
 {
-       kill(bm_pid, SIGKILL);
+       /* Only kill child after bm_pid is set after fork() */
+       if (bm_pid)
+               kill(bm_pid, SIGKILL);
        umount_resctrlfs();
        tests_cleanup();
        ksft_print_msg("Ending\n\n");
@@ -485,6 +487,8 @@ int signal_handler_register(void)
        struct sigaction sigact = {};
        int ret = 0;
 
+       bm_pid = 0;
+
        sigact.sa_sigaction = ctrlc_handler;
        sigemptyset(&sigact.sa_mask);
        sigact.sa_flags = SA_SIGINFO;
@@ -706,10 +710,6 @@ int resctrl_val(const char * const *benchmark_cmd, struct resctrl_val_param *par
 
        ksft_print_msg("Benchmark PID: %d\n", bm_pid);
 
-       ret = signal_handler_register();
-       if (ret)
-               goto out;
-
        /*
         * The cast removes constness but nothing mutates benchmark_cmd within
         * the context of this process. At the receiving process, it becomes
@@ -721,19 +721,19 @@ int resctrl_val(const char * const *benchmark_cmd, struct resctrl_val_param *par
        /* Taskset benchmark to specified cpu */
        ret = taskset_benchmark(bm_pid, param->cpu_no);
        if (ret)
-               goto unregister;
+               goto out;
 
        /* Write benchmark to specified control&monitoring grp in resctrl FS */
        ret = write_bm_pid_to_resctrl(bm_pid, param->ctrlgrp, param->mongrp,
                                      resctrl_val);
        if (ret)
-               goto unregister;
+               goto out;
 
        if (!strncmp(resctrl_val, MBM_STR, sizeof(MBM_STR)) ||
            !strncmp(resctrl_val, MBA_STR, sizeof(MBA_STR))) {
                ret = initialize_mem_bw_imc();
                if (ret)
-                       goto unregister;
+                       goto out;
 
                initialize_mem_bw_resctrl(param->ctrlgrp, param->mongrp,
                                          param->cpu_no, resctrl_val);
@@ -748,7 +748,7 @@ int resctrl_val(const char * const *benchmark_cmd, struct resctrl_val_param *par
                    sizeof(pipe_message)) {
                        perror("# failed reading message from child process");
                        close(pipefd[0]);
-                       goto unregister;
+                       goto out;
                }
        }
        close(pipefd[0]);
@@ -757,7 +757,7 @@ int resctrl_val(const char * const *benchmark_cmd, struct resctrl_val_param *par
        if (sigqueue(bm_pid, SIGUSR1, value) == -1) {
                perror("# sigqueue SIGUSR1 to child");
                ret = errno;
-               goto unregister;
+               goto out;
        }
 
        /* Give benchmark enough time to fully run */
@@ -786,8 +786,6 @@ int resctrl_val(const char * const *benchmark_cmd, struct resctrl_val_param *par
                }
        }
 
-unregister:
-       signal_handler_unregister();
 out:
        kill(bm_pid, SIGKILL);