summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2016-01-07 09:04:03 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2016-01-11 09:36:46 +0000
commitcd658a7c6bca74eb897a8ae87751029793f0c4f4 (patch)
treee9d751b90b31f2de64c244f128020f39f24f200a /lib
parent05ac611358e61f914d99e00e1738f2ff9cfb05d4 (diff)
core/sighelper: Interrupt everyone in the process group
Some stress tests create both the signal helper and a lot of competing processes. In these tests, the parent is just waiting upon the children, and the intention is not to keep waking up the waiting parent, but to keep interrupting the children (as we hope to trigger races in our kernel code). kill(-pid) sends the signal to all members of the process group, not just the target pid. We also switch from using SIGUSR1 to SIGCONT to paper over a race condition when forking children that saw the default signal action being run (and thus killing the child). Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'lib')
-rw-r--r--lib/igt_aux.c21
1 files changed, 17 insertions, 4 deletions
diff --git a/lib/igt_aux.c b/lib/igt_aux.c
index 4d08d68b..ebee119c 100644
--- a/lib/igt_aux.c
+++ b/lib/igt_aux.c
@@ -79,7 +79,7 @@ static void __attribute__((noreturn)) signal_helper_process(pid_t pid)
/* Interrupt the parent process at 500Hz, just to be annoying */
while (1) {
usleep(1000 * 1000 / 500);
- if (kill(pid, SIGUSR1)) /* Parent has died, so must we. */
+ if (kill(pid, SIGCONT)) /* Parent has died, so must we. */
exit(0);
}
}
@@ -93,7 +93,7 @@ static void sig_handler(int i)
* igt_fork_signal_helper:
*
* Fork a child process using #igt_fork_helper to interrupt the parent process
- * with a SIGUSR1 signal at regular quick intervals. The corresponding dummy
+ * with a SIGCONT signal at regular quick intervals. The corresponding dummy
* signal handler is installed in the parent process.
*
* This is useful to exercise ioctl error paths, at least where those can be
@@ -108,10 +108,23 @@ void igt_fork_signal_helper(void)
if (igt_only_list_subtests())
return;
- signal(SIGUSR1, sig_handler);
+ /* We pick SIGCONT as it is a "safe" signal - if we send SIGCONT to
+ * an unexpecting process it spuriously wakes up and does nothing.
+ * Most other signals (e.g. SIGUSR1) cause the process to die if they
+ * are not handled. This is an issue in case the sighandler is not
+ * inherited correctly (or if there is a race in the inheritance
+ * and we send the signal at exactly the wrong time).
+ */
+ signal(SIGCONT, sig_handler);
+ setpgrp(); /* define a new process group for the tests */
igt_fork_helper(&signal_helper) {
- signal_helper_process(getppid());
+ setpgrp(); /* Escape from the test process group */
+
+ /* Pass along the test process group identifier,
+ * negative pid => send signal to everyone in the group.
+ */
+ signal_helper_process(-getppid());
}
}