diff options
Diffstat (limited to 'kernel/exit.c')
-rw-r--r-- | kernel/exit.c | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/kernel/exit.c b/kernel/exit.c index 546774a31a66..ce1e48c2d93d 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
@@ -85,7 +85,9 @@ static void __exit_signal(struct task_struct *tsk) | |||
85 | BUG_ON(!sig); | 85 | BUG_ON(!sig); |
86 | BUG_ON(!atomic_read(&sig->count)); | 86 | BUG_ON(!atomic_read(&sig->count)); |
87 | 87 | ||
88 | sighand = rcu_dereference(tsk->sighand); | 88 | sighand = rcu_dereference_check(tsk->sighand, |
89 | rcu_read_lock_held() || | ||
90 | lockdep_is_held(&tasklist_lock)); | ||
89 | spin_lock(&sighand->siglock); | 91 | spin_lock(&sighand->siglock); |
90 | 92 | ||
91 | posix_cpu_timers_exit(tsk); | 93 | posix_cpu_timers_exit(tsk); |
@@ -170,8 +172,10 @@ void release_task(struct task_struct * p) | |||
170 | repeat: | 172 | repeat: |
171 | tracehook_prepare_release_task(p); | 173 | tracehook_prepare_release_task(p); |
172 | /* don't need to get the RCU readlock here - the process is dead and | 174 | /* don't need to get the RCU readlock here - the process is dead and |
173 | * can't be modifying its own credentials */ | 175 | * can't be modifying its own credentials. But shut RCU-lockdep up */ |
176 | rcu_read_lock(); | ||
174 | atomic_dec(&__task_cred(p)->user->processes); | 177 | atomic_dec(&__task_cred(p)->user->processes); |
178 | rcu_read_unlock(); | ||
175 | 179 | ||
176 | proc_flush_task(p); | 180 | proc_flush_task(p); |
177 | 181 | ||
@@ -473,9 +477,11 @@ static void close_files(struct files_struct * files) | |||
473 | /* | 477 | /* |
474 | * It is safe to dereference the fd table without RCU or | 478 | * It is safe to dereference the fd table without RCU or |
475 | * ->file_lock because this is the last reference to the | 479 | * ->file_lock because this is the last reference to the |
476 | * files structure. | 480 | * files structure. But use RCU to shut RCU-lockdep up. |
477 | */ | 481 | */ |
482 | rcu_read_lock(); | ||
478 | fdt = files_fdtable(files); | 483 | fdt = files_fdtable(files); |
484 | rcu_read_unlock(); | ||
479 | for (;;) { | 485 | for (;;) { |
480 | unsigned long set; | 486 | unsigned long set; |
481 | i = j * __NFDBITS; | 487 | i = j * __NFDBITS; |
@@ -521,10 +527,12 @@ void put_files_struct(struct files_struct *files) | |||
521 | * at the end of the RCU grace period. Otherwise, | 527 | * at the end of the RCU grace period. Otherwise, |
522 | * you can free files immediately. | 528 | * you can free files immediately. |
523 | */ | 529 | */ |
530 | rcu_read_lock(); | ||
524 | fdt = files_fdtable(files); | 531 | fdt = files_fdtable(files); |
525 | if (fdt != &files->fdtab) | 532 | if (fdt != &files->fdtab) |
526 | kmem_cache_free(files_cachep, files); | 533 | kmem_cache_free(files_cachep, files); |
527 | free_fdtable(fdt); | 534 | free_fdtable(fdt); |
535 | rcu_read_unlock(); | ||
528 | } | 536 | } |
529 | } | 537 | } |
530 | 538 | ||
@@ -944,7 +952,8 @@ NORET_TYPE void do_exit(long code) | |||
944 | preempt_count()); | 952 | preempt_count()); |
945 | 953 | ||
946 | acct_update_integrals(tsk); | 954 | acct_update_integrals(tsk); |
947 | 955 | /* sync mm's RSS info before statistics gathering */ | |
956 | sync_mm_rss(tsk, tsk->mm); | ||
948 | group_dead = atomic_dec_and_test(&tsk->signal->live); | 957 | group_dead = atomic_dec_and_test(&tsk->signal->live); |
949 | if (group_dead) { | 958 | if (group_dead) { |
950 | hrtimer_cancel(&tsk->signal->real_timer); | 959 | hrtimer_cancel(&tsk->signal->real_timer); |
@@ -1180,7 +1189,7 @@ static int wait_task_zombie(struct wait_opts *wo, struct task_struct *p) | |||
1180 | 1189 | ||
1181 | if (unlikely(wo->wo_flags & WNOWAIT)) { | 1190 | if (unlikely(wo->wo_flags & WNOWAIT)) { |
1182 | int exit_code = p->exit_code; | 1191 | int exit_code = p->exit_code; |
1183 | int why, status; | 1192 | int why; |
1184 | 1193 | ||
1185 | get_task_struct(p); | 1194 | get_task_struct(p); |
1186 | read_unlock(&tasklist_lock); | 1195 | read_unlock(&tasklist_lock); |