summaryrefslogtreecommitdiffstats
path: root/include/linux/sched
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2018-07-23 13:38:00 -0500
committerEric W. Biederman <ebiederm@xmission.com>2018-08-03 20:20:14 -0500
commit924de3b8c9410c404c6eda7abffd282b97b3ff7f (patch)
tree6bcc1ed1e1a9268ad6ce8c899d9e728e769277fb /include/linux/sched
parent4390e9eadbbb6774b7ba03fde0a0fdf3f07db4cd (diff)
downloadlinux-924de3b8c9410c404c6eda7abffd282b97b3ff7f.tar.gz
linux-924de3b8c9410c404c6eda7abffd282b97b3ff7f.tar.bz2
linux-924de3b8c9410c404c6eda7abffd282b97b3ff7f.zip
fork: Have new threads join on-going signal group stops
There are only two signals that are delivered to every member of a signal group: SIGSTOP and SIGKILL. Signal delivery requires every signal appear to be delivered either before or after a clone syscall. SIGKILL terminates the clone so does not need to be considered. Which leaves only SIGSTOP that needs to be considered when creating new threads. Today in the event of a group stop TIF_SIGPENDING will get set and the fork will restart ensuring the fork syscall participates in the group stop. A fork (especially of a process with a lot of memory) is one of the most expensive system so we really only want to restart a fork when necessary. It is easy so check to see if a SIGSTOP is ongoing and have the new thread join it immediate after the clone completes. Making it appear the clone completed happened just before the SIGSTOP. The calculate_sigpending function will see the bits set in jobctl and set TIF_SIGPENDING to ensure the new task takes the slow path to userspace. V2: The call to task_join_group_stop was moved before the new task is added to the thread group list. This should not matter as sighand->siglock is held over both the addition of the threads, the call to task_join_group_stop and do_signal_stop. But the change is trivial and it is one less thing to worry about when reading the code. Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
Diffstat (limited to 'include/linux/sched')
-rw-r--r--include/linux/sched/signal.h2
1 files changed, 2 insertions, 0 deletions
diff --git a/include/linux/sched/signal.h b/include/linux/sched/signal.h
index b55fd293c1e5..ae2b0b81be25 100644
--- a/include/linux/sched/signal.h
+++ b/include/linux/sched/signal.h
@@ -385,6 +385,8 @@ static inline void ptrace_signal_wake_up(struct task_struct *t, bool resume)
signal_wake_up_state(t, resume ? __TASK_TRACED : 0);
}
+void task_join_group_stop(struct task_struct *task);
+
#ifdef TIF_RESTORE_SIGMASK
/*
* Legacy restore_sigmask accessors. These are inefficient on