diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/exit.c | 23 |
1 files changed, 11 insertions, 12 deletions
diff --git a/kernel/exit.c b/kernel/exit.c index 20875d6398ae..457673d65934 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
@@ -1010,8 +1010,8 @@ static int wait_task_zombie(struct wait_opts *wo, struct task_struct *p) | |||
1010 | * Check thread_group_leader() to exclude the traced sub-threads. | 1010 | * Check thread_group_leader() to exclude the traced sub-threads. |
1011 | */ | 1011 | */ |
1012 | if (state == EXIT_DEAD && thread_group_leader(p)) { | 1012 | if (state == EXIT_DEAD && thread_group_leader(p)) { |
1013 | struct signal_struct *psig; | 1013 | struct signal_struct *sig = p->signal; |
1014 | struct signal_struct *sig; | 1014 | struct signal_struct *psig = current->signal; |
1015 | unsigned long maxrss; | 1015 | unsigned long maxrss; |
1016 | cputime_t tgutime, tgstime; | 1016 | cputime_t tgutime, tgstime; |
1017 | 1017 | ||
@@ -1023,21 +1023,20 @@ static int wait_task_zombie(struct wait_opts *wo, struct task_struct *p) | |||
1023 | * accumulate in the parent's signal_struct c* fields. | 1023 | * accumulate in the parent's signal_struct c* fields. |
1024 | * | 1024 | * |
1025 | * We don't bother to take a lock here to protect these | 1025 | * We don't bother to take a lock here to protect these |
1026 | * p->signal fields, because they are only touched by | 1026 | * p->signal fields because the whole thread group is dead |
1027 | * __exit_signal, which runs with tasklist_lock | 1027 | * and nobody can change them. |
1028 | * write-locked anyway, and so is excluded here. We do | 1028 | * |
1029 | * need to protect the access to parent->signal fields, | 1029 | * psig->stats_lock also protects us from our sub-theads |
1030 | * as other threads in the parent group can be right | 1030 | * which can reap other children at the same time. Until |
1031 | * here reaping other children at the same time. | 1031 | * we change k_getrusage()-like users to rely on this lock |
1032 | * we have to take ->siglock as well. | ||
1032 | * | 1033 | * |
1033 | * We use thread_group_cputime_adjusted() to get times for | 1034 | * We use thread_group_cputime_adjusted() to get times for |
1034 | * the thread group, which consolidates times for all threads | 1035 | * the thread group, which consolidates times for all threads |
1035 | * in the group including the group leader. | 1036 | * in the group including the group leader. |
1036 | */ | 1037 | */ |
1037 | thread_group_cputime_adjusted(p, &tgutime, &tgstime); | 1038 | thread_group_cputime_adjusted(p, &tgutime, &tgstime); |
1038 | spin_lock_irq(&p->real_parent->sighand->siglock); | 1039 | spin_lock_irq(¤t->sighand->siglock); |
1039 | psig = p->real_parent->signal; | ||
1040 | sig = p->signal; | ||
1041 | write_seqlock(&psig->stats_lock); | 1040 | write_seqlock(&psig->stats_lock); |
1042 | psig->cutime += tgutime + sig->cutime; | 1041 | psig->cutime += tgutime + sig->cutime; |
1043 | psig->cstime += tgstime + sig->cstime; | 1042 | psig->cstime += tgstime + sig->cstime; |
@@ -1062,7 +1061,7 @@ static int wait_task_zombie(struct wait_opts *wo, struct task_struct *p) | |||
1062 | task_io_accounting_add(&psig->ioac, &p->ioac); | 1061 | task_io_accounting_add(&psig->ioac, &p->ioac); |
1063 | task_io_accounting_add(&psig->ioac, &sig->ioac); | 1062 | task_io_accounting_add(&psig->ioac, &sig->ioac); |
1064 | write_sequnlock(&psig->stats_lock); | 1063 | write_sequnlock(&psig->stats_lock); |
1065 | spin_unlock_irq(&p->real_parent->sighand->siglock); | 1064 | spin_unlock_irq(¤t->sighand->siglock); |
1066 | } | 1065 | } |
1067 | 1066 | ||
1068 | /* | 1067 | /* |