Hi,

I noticed some hangs while running perf_events kselftests on some
RISC-V boards with potentially broken PMU overflow interrupts. It
looked like the timeouts worked properly and killed the first 3 jobs,
but the 4th one would just hang and never timeout.

# timeout set to 120
# selftests: perf_events: remove_on_exec
# TAP version 13
# 1..4
# # Starting 4 tests from 1 test cases.
# #  RUN           remove_on_exec.fork_only ...
# # fork_only: Test terminated by timeout
# #          FAIL  remove_on_exec.fork_only
# not ok 1 remove_on_exec.fork_only
# #  RUN           remove_on_exec.fork_exec_then_enable ...
# # fork_exec_then_enable: Test terminated by timeout
# #          FAIL  remove_on_exec.fork_exec_then_enable
# not ok 2 remove_on_exec.fork_exec_then_enable
# #  RUN           remove_on_exec.enable_then_fork_exec ...
# *# enable_then_fork_exec: Test terminated by timeout
# #          FAIL  remove_on_exec.enable_then_fork_exec
# not ok 3 remove_on_exec.enable_then_fork_exec
# #  RUN           remove_on_exec.exec_stress ...

This hang can be simulated on any host by adding an infinite loop at
the beginning of these 4 tests.

diff --git a/tools/testing/selftests/perf_events/remove_on_exec.c
b/tools/testing/selftests/perf_events/remove_on_exec.c
index 89e7b06835df..d9a76351efa6 100644
--- a/tools/testing/selftests/perf_events/remove_on_exec.c
+++ b/tools/testing/selftests/perf_events/remove_on_exec.c
@@ -99,6 +99,7 @@ FIXTURE_TEARDOWN(remove_on_exec)
 /* Verify event propagates to fork'd child. */
 TEST_F(remove_on_exec, fork_only)
 {
+       while(true);
        int status;
        pid_t pid = fork();

@@ -120,6 +121,7 @@ TEST_F(remove_on_exec, fork_only)
  */
 TEST_F(remove_on_exec, fork_exec_then_enable)
 {
+       while(true);
        pid_t pid_exec, pid_only_fork;
        int pipefd[2];
        int tmp;
@@ -171,6 +173,7 @@ TEST_F(remove_on_exec, fork_exec_then_enable)
  */
 TEST_F(remove_on_exec, enable_then_fork_exec)
 {
+       while(true);
        pid_t pid_exec;
        int tmp;

@@ -197,6 +200,7 @@ TEST_F(remove_on_exec, enable_then_fork_exec)

 TEST_F(remove_on_exec, exec_stress)
 {
+       while(true);
        pid_t pids[30];
        int i, tmp;

Then run like this
./run_kselftest.sh --test perf_events:remove_on_exec

Some digging around showed that there are 2 sets of timeouts, one is a
120s timeout imposed by the runner script (run_kselftest.sh) and
another is a 30s timer for each test process by the kselftest harness
(kselftest_harness.h). The harness's 30s timer causes the first 3
fails (at 30s, 60s, 90s), but neither of the timers seem to cause the
4th job to fail when we hit 120s.

It appears that the harness launches each test within its own process
group using setpgrp(), which might prevent the kill signal from the
runner at 120s from propagating to the test process.

This bug can affect other tests that timeout too. I'm not sure what
the best solution is here, and was hoping someone else could chime in.

Regards
Anirudh Srinivasan

Reply via email to