Commit 183986a7 authored by Roland McGrath's avatar Roland McGrath Committed by Linus Torvalds

[PATCH] move group_exit flag into signal_struct.flags word

After my last change, there are plenty of unused bits available in the new
flags word in signal_struct.  This patch moves the `group_exit' flag into
one of those bits, saving a word in signal_struct.
Signed-off-by: default avatarRoland McGrath <roland@redhat.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 0b4eff5d
...@@ -601,7 +601,7 @@ static inline int de_thread(struct task_struct *tsk) ...@@ -601,7 +601,7 @@ static inline int de_thread(struct task_struct *tsk)
*/ */
read_lock(&tasklist_lock); read_lock(&tasklist_lock);
spin_lock_irq(lock); spin_lock_irq(lock);
if (sig->group_exit) { if (sig->flags & SIGNAL_GROUP_EXIT) {
/* /*
* Another group action in progress, just * Another group action in progress, just
* return so that the signal is processed. * return so that the signal is processed.
...@@ -611,7 +611,6 @@ static inline int de_thread(struct task_struct *tsk) ...@@ -611,7 +611,6 @@ static inline int de_thread(struct task_struct *tsk)
kmem_cache_free(sighand_cachep, newsighand); kmem_cache_free(sighand_cachep, newsighand);
return -EAGAIN; return -EAGAIN;
} }
sig->group_exit = 1;
zap_other_threads(current); zap_other_threads(current);
read_unlock(&tasklist_lock); read_unlock(&tasklist_lock);
...@@ -709,7 +708,7 @@ static inline int de_thread(struct task_struct *tsk) ...@@ -709,7 +708,7 @@ static inline int de_thread(struct task_struct *tsk)
* Now there are really no other threads at all, * Now there are really no other threads at all,
* so it's safe to stop telling them to kill themselves. * so it's safe to stop telling them to kill themselves.
*/ */
sig->group_exit = 0; sig->flags = 0;
no_thread_group: no_thread_group:
BUG_ON(atomic_read(&sig->count) != 1); BUG_ON(atomic_read(&sig->count) != 1);
...@@ -1396,7 +1395,7 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs) ...@@ -1396,7 +1395,7 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
} }
mm->dumpable = 0; mm->dumpable = 0;
init_completion(&mm->core_done); init_completion(&mm->core_done);
current->signal->group_exit = 1; current->signal->flags = SIGNAL_GROUP_EXIT;
current->signal->group_exit_code = exit_code; current->signal->group_exit_code = exit_code;
coredump_wait(mm); coredump_wait(mm);
......
...@@ -281,7 +281,6 @@ struct signal_struct { ...@@ -281,7 +281,6 @@ struct signal_struct {
struct sigpending shared_pending; struct sigpending shared_pending;
/* thread group exit support */ /* thread group exit support */
int group_exit;
int group_exit_code; int group_exit_code;
/* overloaded: /* overloaded:
* - notify group_exit_task when ->count is equal to notify_count * - notify group_exit_task when ->count is equal to notify_count
...@@ -335,6 +334,7 @@ struct signal_struct { ...@@ -335,6 +334,7 @@ struct signal_struct {
#define SIGNAL_STOP_STOPPED 0x00000001 /* job control stop in effect */ #define SIGNAL_STOP_STOPPED 0x00000001 /* job control stop in effect */
#define SIGNAL_STOP_DEQUEUED 0x00000002 /* stop signal dequeued */ #define SIGNAL_STOP_DEQUEUED 0x00000002 /* stop signal dequeued */
#define SIGNAL_STOP_CONTINUED 0x00000004 /* SIGCONT since WCONTINUED reap */ #define SIGNAL_STOP_CONTINUED 0x00000004 /* SIGCONT since WCONTINUED reap */
#define SIGNAL_GROUP_EXIT 0x00000008 /* group exit in progress */
/* /*
......
...@@ -656,7 +656,7 @@ static void exit_notify(struct task_struct *tsk) ...@@ -656,7 +656,7 @@ static void exit_notify(struct task_struct *tsk)
struct task_struct *t; struct task_struct *t;
struct list_head ptrace_dead, *_p, *_n; struct list_head ptrace_dead, *_p, *_n;
if (signal_pending(tsk) && !tsk->signal->group_exit if (signal_pending(tsk) && !(tsk->signal->flags & SIGNAL_GROUP_EXIT)
&& !thread_group_empty(tsk)) { && !thread_group_empty(tsk)) {
/* /*
* This occurs when there was a race between our exit * This occurs when there was a race between our exit
...@@ -879,18 +879,18 @@ do_group_exit(int exit_code) ...@@ -879,18 +879,18 @@ do_group_exit(int exit_code)
{ {
BUG_ON(exit_code & 0x80); /* core dumps don't get here */ BUG_ON(exit_code & 0x80); /* core dumps don't get here */
if (current->signal->group_exit) if (current->signal->flags & SIGNAL_GROUP_EXIT)
exit_code = current->signal->group_exit_code; exit_code = current->signal->group_exit_code;
else if (!thread_group_empty(current)) { else if (!thread_group_empty(current)) {
struct signal_struct *const sig = current->signal; struct signal_struct *const sig = current->signal;
struct sighand_struct *const sighand = current->sighand; struct sighand_struct *const sighand = current->sighand;
read_lock(&tasklist_lock); read_lock(&tasklist_lock);
spin_lock_irq(&sighand->siglock); spin_lock_irq(&sighand->siglock);
if (sig->group_exit) if (sig->flags & SIGNAL_GROUP_EXIT)
/* Another thread got here before we took the lock. */ /* Another thread got here before we took the lock. */
exit_code = sig->group_exit_code; exit_code = sig->group_exit_code;
else { else {
sig->group_exit = 1; sig->flags = SIGNAL_GROUP_EXIT;
sig->group_exit_code = exit_code; sig->group_exit_code = exit_code;
zap_other_threads(current); zap_other_threads(current);
} }
...@@ -1070,7 +1070,7 @@ static int wait_task_zombie(task_t *p, int noreap, ...@@ -1070,7 +1070,7 @@ static int wait_task_zombie(task_t *p, int noreap,
read_unlock(&tasklist_lock); read_unlock(&tasklist_lock);
retval = ru ? getrusage(p, RUSAGE_BOTH, ru) : 0; retval = ru ? getrusage(p, RUSAGE_BOTH, ru) : 0;
status = p->signal->group_exit status = (p->signal->flags & SIGNAL_GROUP_EXIT)
? p->signal->group_exit_code : p->exit_code; ? p->signal->group_exit_code : p->exit_code;
if (!retval && stat_addr) if (!retval && stat_addr)
retval = put_user(status, stat_addr); retval = put_user(status, stat_addr);
......
...@@ -734,7 +734,6 @@ static inline int copy_signal(unsigned long clone_flags, struct task_struct * ts ...@@ -734,7 +734,6 @@ static inline int copy_signal(unsigned long clone_flags, struct task_struct * ts
atomic_set(&sig->count, 1); atomic_set(&sig->count, 1);
atomic_set(&sig->live, 1); atomic_set(&sig->live, 1);
sig->flags = 0; sig->flags = 0;
sig->group_exit = 0;
sig->group_exit_code = 0; sig->group_exit_code = 0;
sig->group_exit_task = NULL; sig->group_exit_task = NULL;
sig->group_stop_count = 0; sig->group_stop_count = 0;
...@@ -1000,7 +999,7 @@ static task_t *copy_process(unsigned long clone_flags, ...@@ -1000,7 +999,7 @@ static task_t *copy_process(unsigned long clone_flags,
* do not create this new thread - the whole thread * do not create this new thread - the whole thread
* group is supposed to exit anyway. * group is supposed to exit anyway.
*/ */
if (current->signal->group_exit) { if (current->signal->flags & SIGNAL_GROUP_EXIT) {
spin_unlock(&current->sighand->siglock); spin_unlock(&current->sighand->siglock);
write_unlock_irq(&tasklist_lock); write_unlock_irq(&tasklist_lock);
retval = -EAGAIN; retval = -EAGAIN;
......
...@@ -661,6 +661,12 @@ static void handle_stop_signal(int sig, struct task_struct *p) ...@@ -661,6 +661,12 @@ static void handle_stop_signal(int sig, struct task_struct *p)
{ {
struct task_struct *t; struct task_struct *t;
if (p->flags & SIGNAL_GROUP_EXIT)
/*
* The process is in the middle of dying already.
*/
return;
if (sig_kernel_stop(sig)) { if (sig_kernel_stop(sig)) {
/* /*
* This is a stop signal. Remove SIGCONT from all queues. * This is a stop signal. Remove SIGCONT from all queues.
...@@ -976,7 +982,7 @@ __group_complete_signal(int sig, struct task_struct *p) ...@@ -976,7 +982,7 @@ __group_complete_signal(int sig, struct task_struct *p)
* Found a killable thread. If the signal will be fatal, * Found a killable thread. If the signal will be fatal,
* then start taking the whole group down immediately. * then start taking the whole group down immediately.
*/ */
if (sig_fatal(p, sig) && !p->signal->group_exit && if (sig_fatal(p, sig) && !(p->signal->flags & SIGNAL_GROUP_EXIT) &&
!sigismember(&t->real_blocked, sig) && !sigismember(&t->real_blocked, sig) &&
(sig == SIGKILL || !(t->ptrace & PT_PTRACED))) { (sig == SIGKILL || !(t->ptrace & PT_PTRACED))) {
/* /*
...@@ -989,10 +995,9 @@ __group_complete_signal(int sig, struct task_struct *p) ...@@ -989,10 +995,9 @@ __group_complete_signal(int sig, struct task_struct *p)
* running and doing things after a slower * running and doing things after a slower
* thread has the fatal signal pending. * thread has the fatal signal pending.
*/ */
p->signal->group_exit = 1; p->signal->flags = SIGNAL_GROUP_EXIT;
p->signal->group_exit_code = sig; p->signal->group_exit_code = sig;
p->signal->group_stop_count = 0; p->signal->group_stop_count = 0;
p->signal->flags = 0;
t = p; t = p;
do { do {
sigaddset(&t->pending.signal, SIGKILL); sigaddset(&t->pending.signal, SIGKILL);
...@@ -1079,8 +1084,8 @@ void zap_other_threads(struct task_struct *p) ...@@ -1079,8 +1084,8 @@ void zap_other_threads(struct task_struct *p)
{ {
struct task_struct *t; struct task_struct *t;
p->signal->flags = SIGNAL_GROUP_EXIT;
p->signal->group_stop_count = 0; p->signal->group_stop_count = 0;
p->signal->flags = 0;
if (thread_group_empty(p)) if (thread_group_empty(p))
return; return;
...@@ -1785,7 +1790,7 @@ static inline int handle_group_stop(void) ...@@ -1785,7 +1790,7 @@ static inline int handle_group_stop(void)
return 0; return 0;
} }
if (current->signal->group_exit) if (current->signal->flags & SIGNAL_GROUP_EXIT)
/* /*
* Group stop is so another thread can do a core dump, * Group stop is so another thread can do a core dump,
* or else we are racing against a death signal. * or else we are racing against a death signal.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment