[Intel-gfx] [PATCH i-g-t v2 1/2] aux: Suspend signal helper for shell commands

Imre Deak imre.deak at intel.com
Fri Oct 13 11:30:08 UTC 2017


The clone() system call with a larger executable (like /bin/sh) may have
difficulty to make progress on some platforms if interrupted frequently.
So suspend the signal helper process for the duration of the syscall.
This is needed to solve an actual problem by the next patch.

v2:
- Clarify/fix code comments. (Chris)
- Update igt_system_quiet() as well accordingly.

Cc: Chris Wilson <chris at chris-wilson.co.uk>
Cc: Daniel Vetter <daniel.vetter at intel.com>
Signed-off-by: Imre Deak <imre.deak at intel.com>
Reviewed-by: Chris Wilson <chris at chris-wilson.co.uk> (v1)
---
 lib/igt_aux.c  | 38 ++++++++++++++++++++++++++++++++++++++
 lib/igt_aux.h  |  2 ++
 lib/igt_core.c | 16 ++++++++++++++++
 3 files changed, 56 insertions(+)

diff --git a/lib/igt_aux.c b/lib/igt_aux.c
index fa6594c3..8dde9a12 100644
--- a/lib/igt_aux.c
+++ b/lib/igt_aux.c
@@ -350,6 +350,44 @@ void igt_stop_signal_helper(void)
 	sig_stat = 0;
 }
 
+/**
+ * igt_suspend_signal_helper:
+ *
+ * Suspends the child process spawned with igt_fork_signal_helper(). This
+ * should be called before a critical section of code that has difficulty to
+ * make progress if interrupted frequently, like the clone() syscall called
+ * from a largish executable. igt_resume_signal_helper() must be called after
+ * the critical section to restart interruptions for the test.
+ */
+void igt_suspend_signal_helper(void)
+{
+	int status;
+
+	if (!signal_helper.running)
+		return;
+
+	kill(signal_helper.pid, SIGSTOP);
+	while (waitpid(signal_helper.pid, &status, WUNTRACED) == -1 &&
+	       errno == EINTR)
+		;
+}
+
+/**
+ * igt_resume_signal_helper:
+ *
+ * Resumes the child process spawned with igt_fork_signal_helper().
+ *
+ * This should be paired with igt_suspend_signal_helper() and called after the
+ * problematic code sensitive to signals.
+ */
+void igt_resume_signal_helper(void)
+{
+	if (!signal_helper.running)
+		return;
+
+	kill(signal_helper.pid, SIGCONT);
+}
+
 static struct igt_helper_process shrink_helper;
 static void __attribute__((noreturn)) shrink_helper_process(int fd, pid_t pid)
 {
diff --git a/lib/igt_aux.h b/lib/igt_aux.h
index 499a1679..688ad1b8 100644
--- a/lib/igt_aux.h
+++ b/lib/igt_aux.h
@@ -55,6 +55,8 @@ extern int num_trash_bos;
 /* generally useful helpers */
 void igt_fork_signal_helper(void);
 void igt_stop_signal_helper(void);
+void igt_suspend_signal_helper(void);
+void igt_resume_signal_helper(void);
 
 void igt_fork_shrink_helper(int fd);
 void igt_stop_shrink_helper(void);
diff --git a/lib/igt_core.c b/lib/igt_core.c
index 950ea9b0..538a4472 100644
--- a/lib/igt_core.c
+++ b/lib/igt_core.c
@@ -2282,6 +2282,13 @@ int igt_system(const char *command)
 	if (pipe(errpipe) < 0)
 		goto err;
 
+	/*
+	 * The clone() system call called from a largish executable has
+	 * difficulty to make progress if interrupted too frequently, so
+	 * suspend the signal helper for the time of the syscall.
+	 */
+	igt_suspend_signal_helper();
+
 	igt_fork_helper(&process) {
 		close(outpipe[0]);
 		close(errpipe[0]);
@@ -2298,6 +2305,8 @@ int igt_system(const char *command)
 		exit(EXIT_FAILURE);
 	}
 
+	igt_resume_signal_helper();
+
 	close(outpipe[1]);
 	close(errpipe[1]);
 
@@ -2340,9 +2349,14 @@ int igt_system_quiet(const char *command)
 	if (dup2(nullfd, STDERR_FILENO) == -1)
 		goto err;
 
+	/* See igt_system() for the reason for suspending the signal helper. */
+	igt_suspend_signal_helper();
+
 	if ((status = system(command)) == -1)
 		goto err;
 
+	igt_resume_signal_helper();
+
 	/* restore */
 	if (dup2(stdout_fd_copy, STDOUT_FILENO) == -1)
 		goto err;
@@ -2355,6 +2369,8 @@ int igt_system_quiet(const char *command)
 
 	return WEXITSTATUS(status);
 err:
+	igt_resume_signal_helper();
+
 	close(stderr_fd_copy);
 	close(stdout_fd_copy);
 	close(nullfd);
-- 
2.13.2



More information about the Intel-gfx mailing list