diff options
author | Ingo Molnar <mingo@elte.hu> | 2008-07-26 11:48:49 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-07-26 11:48:49 -0400 |
commit | c3cc99ff5d24e2eeaf7ec2032e720681916990e3 (patch) | |
tree | c3e74171bbbd2adde9d60b9db1c440415c8d2831 /kernel/exit.c | |
parent | 38ffbe66d59051fd9cfcfc8545f164700e2fa3bc (diff) | |
parent | 024e8ac04453b3525448c31ef39848cf675ba6db (diff) |
Merge branch 'linus' into x86/xen
Diffstat (limited to 'kernel/exit.c')
-rw-r--r-- | kernel/exit.c | 61 |
1 files changed, 50 insertions, 11 deletions
diff --git a/kernel/exit.c b/kernel/exit.c index 93d2711b9381..ad933bb29ec7 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
@@ -85,7 +85,6 @@ 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 | rcu_read_lock(); | ||
89 | sighand = rcu_dereference(tsk->sighand); | 88 | sighand = rcu_dereference(tsk->sighand); |
90 | spin_lock(&sighand->siglock); | 89 | spin_lock(&sighand->siglock); |
91 | 90 | ||
@@ -121,6 +120,18 @@ static void __exit_signal(struct task_struct *tsk) | |||
121 | sig->nivcsw += tsk->nivcsw; | 120 | sig->nivcsw += tsk->nivcsw; |
122 | sig->inblock += task_io_get_inblock(tsk); | 121 | sig->inblock += task_io_get_inblock(tsk); |
123 | sig->oublock += task_io_get_oublock(tsk); | 122 | sig->oublock += task_io_get_oublock(tsk); |
123 | #ifdef CONFIG_TASK_XACCT | ||
124 | sig->rchar += tsk->rchar; | ||
125 | sig->wchar += tsk->wchar; | ||
126 | sig->syscr += tsk->syscr; | ||
127 | sig->syscw += tsk->syscw; | ||
128 | #endif /* CONFIG_TASK_XACCT */ | ||
129 | #ifdef CONFIG_TASK_IO_ACCOUNTING | ||
130 | sig->ioac.read_bytes += tsk->ioac.read_bytes; | ||
131 | sig->ioac.write_bytes += tsk->ioac.write_bytes; | ||
132 | sig->ioac.cancelled_write_bytes += | ||
133 | tsk->ioac.cancelled_write_bytes; | ||
134 | #endif /* CONFIG_TASK_IO_ACCOUNTING */ | ||
124 | sig->sum_sched_runtime += tsk->se.sum_exec_runtime; | 135 | sig->sum_sched_runtime += tsk->se.sum_exec_runtime; |
125 | sig = NULL; /* Marker for below. */ | 136 | sig = NULL; /* Marker for below. */ |
126 | } | 137 | } |
@@ -136,7 +147,6 @@ static void __exit_signal(struct task_struct *tsk) | |||
136 | tsk->signal = NULL; | 147 | tsk->signal = NULL; |
137 | tsk->sighand = NULL; | 148 | tsk->sighand = NULL; |
138 | spin_unlock(&sighand->siglock); | 149 | spin_unlock(&sighand->siglock); |
139 | rcu_read_unlock(); | ||
140 | 150 | ||
141 | __cleanup_sighand(sighand); | 151 | __cleanup_sighand(sighand); |
142 | clear_tsk_thread_flag(tsk,TIF_SIGPENDING); | 152 | clear_tsk_thread_flag(tsk,TIF_SIGPENDING); |
@@ -432,7 +442,7 @@ void daemonize(const char *name, ...) | |||
432 | * We don't want to have TIF_FREEZE set if the system-wide hibernation | 442 | * We don't want to have TIF_FREEZE set if the system-wide hibernation |
433 | * or suspend transition begins right now. | 443 | * or suspend transition begins right now. |
434 | */ | 444 | */ |
435 | current->flags |= PF_NOFREEZE; | 445 | current->flags |= (PF_NOFREEZE | PF_KTHREAD); |
436 | 446 | ||
437 | if (current->nsproxy != &init_nsproxy) { | 447 | if (current->nsproxy != &init_nsproxy) { |
438 | get_nsproxy(&init_nsproxy); | 448 | get_nsproxy(&init_nsproxy); |
@@ -666,26 +676,40 @@ assign_new_owner: | |||
666 | static void exit_mm(struct task_struct * tsk) | 676 | static void exit_mm(struct task_struct * tsk) |
667 | { | 677 | { |
668 | struct mm_struct *mm = tsk->mm; | 678 | struct mm_struct *mm = tsk->mm; |
679 | struct core_state *core_state; | ||
669 | 680 | ||
670 | mm_release(tsk, mm); | 681 | mm_release(tsk, mm); |
671 | if (!mm) | 682 | if (!mm) |
672 | return; | 683 | return; |
673 | /* | 684 | /* |
674 | * Serialize with any possible pending coredump. | 685 | * Serialize with any possible pending coredump. |
675 | * We must hold mmap_sem around checking core_waiters | 686 | * We must hold mmap_sem around checking core_state |
676 | * and clearing tsk->mm. The core-inducing thread | 687 | * and clearing tsk->mm. The core-inducing thread |
677 | * will increment core_waiters for each thread in the | 688 | * will increment ->nr_threads for each thread in the |
678 | * group with ->mm != NULL. | 689 | * group with ->mm != NULL. |
679 | */ | 690 | */ |
680 | down_read(&mm->mmap_sem); | 691 | down_read(&mm->mmap_sem); |
681 | if (mm->core_waiters) { | 692 | core_state = mm->core_state; |
693 | if (core_state) { | ||
694 | struct core_thread self; | ||
682 | up_read(&mm->mmap_sem); | 695 | up_read(&mm->mmap_sem); |
683 | down_write(&mm->mmap_sem); | ||
684 | if (!--mm->core_waiters) | ||
685 | complete(mm->core_startup_done); | ||
686 | up_write(&mm->mmap_sem); | ||
687 | 696 | ||
688 | wait_for_completion(&mm->core_done); | 697 | self.task = tsk; |
698 | self.next = xchg(&core_state->dumper.next, &self); | ||
699 | /* | ||
700 | * Implies mb(), the result of xchg() must be visible | ||
701 | * to core_state->dumper. | ||
702 | */ | ||
703 | if (atomic_dec_and_test(&core_state->nr_threads)) | ||
704 | complete(&core_state->startup); | ||
705 | |||
706 | for (;;) { | ||
707 | set_task_state(tsk, TASK_UNINTERRUPTIBLE); | ||
708 | if (!self.task) /* see coredump_finish() */ | ||
709 | break; | ||
710 | schedule(); | ||
711 | } | ||
712 | __set_task_state(tsk, TASK_RUNNING); | ||
689 | down_read(&mm->mmap_sem); | 713 | down_read(&mm->mmap_sem); |
690 | } | 714 | } |
691 | atomic_inc(&mm->mm_count); | 715 | atomic_inc(&mm->mm_count); |
@@ -1354,6 +1378,21 @@ static int wait_task_zombie(struct task_struct *p, int options, | |||
1354 | psig->coublock += | 1378 | psig->coublock += |
1355 | task_io_get_oublock(p) + | 1379 | task_io_get_oublock(p) + |
1356 | sig->oublock + sig->coublock; | 1380 | sig->oublock + sig->coublock; |
1381 | #ifdef CONFIG_TASK_XACCT | ||
1382 | psig->rchar += p->rchar + sig->rchar; | ||
1383 | psig->wchar += p->wchar + sig->wchar; | ||
1384 | psig->syscr += p->syscr + sig->syscr; | ||
1385 | psig->syscw += p->syscw + sig->syscw; | ||
1386 | #endif /* CONFIG_TASK_XACCT */ | ||
1387 | #ifdef CONFIG_TASK_IO_ACCOUNTING | ||
1388 | psig->ioac.read_bytes += | ||
1389 | p->ioac.read_bytes + sig->ioac.read_bytes; | ||
1390 | psig->ioac.write_bytes += | ||
1391 | p->ioac.write_bytes + sig->ioac.write_bytes; | ||
1392 | psig->ioac.cancelled_write_bytes += | ||
1393 | p->ioac.cancelled_write_bytes + | ||
1394 | sig->ioac.cancelled_write_bytes; | ||
1395 | #endif /* CONFIG_TASK_IO_ACCOUNTING */ | ||
1357 | spin_unlock_irq(&p->parent->sighand->siglock); | 1396 | spin_unlock_irq(&p->parent->sighand->siglock); |
1358 | } | 1397 | } |
1359 | 1398 | ||