diff --git a/[refs] b/[refs] index 2cd34599e675..1ff37707d0a4 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 8cd9c249128a59e8e833d454a784b0cbd338d468 +refs/heads/master: c5f1cc8c1828486a61ab3e575da6e2c62b34d399 diff --git a/trunk/fs/exec.c b/trunk/fs/exec.c index c74bb34eeeff..15d493fe8aa3 100644 --- a/trunk/fs/exec.c +++ b/trunk/fs/exec.c @@ -1591,7 +1591,7 @@ static inline int zap_threads(struct task_struct *tsk, struct mm_struct *mm, } rcu_read_unlock(); done: - core_state->nr_threads = nr; + atomic_set(&core_state->nr_threads, nr); return nr; } diff --git a/trunk/include/linux/mm_types.h b/trunk/include/linux/mm_types.h index c0b1747b61a5..ae99a28ba6ae 100644 --- a/trunk/include/linux/mm_types.h +++ b/trunk/include/linux/mm_types.h @@ -160,7 +160,7 @@ struct vm_area_struct { }; struct core_state { - int nr_threads; + atomic_t nr_threads; struct completion startup; }; diff --git a/trunk/kernel/exit.c b/trunk/kernel/exit.c index 988e232254e9..63d82957baae 100644 --- a/trunk/kernel/exit.c +++ b/trunk/kernel/exit.c @@ -678,10 +678,9 @@ static void exit_mm(struct task_struct * tsk) down_read(&mm->mmap_sem); if (mm->core_state) { up_read(&mm->mmap_sem); - down_write(&mm->mmap_sem); - if (!--mm->core_state->nr_threads) + + if (atomic_dec_and_test(&mm->core_state->nr_threads)) complete(&mm->core_state->startup); - up_write(&mm->mmap_sem); wait_for_completion(&mm->core_done); down_read(&mm->mmap_sem);