aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/exit.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2008-07-26 11:48:49 -0400
committerIngo Molnar <mingo@elte.hu>2008-07-26 11:48:49 -0400
commitc3cc99ff5d24e2eeaf7ec2032e720681916990e3 (patch)
treec3e74171bbbd2adde9d60b9db1c440415c8d2831 /kernel/exit.c
parent38ffbe66d59051fd9cfcfc8545f164700e2fa3bc (diff)
parent024e8ac04453b3525448c31ef39848cf675ba6db (diff)
Merge branch 'linus' into x86/xen
Diffstat (limited to 'kernel/exit.c')
-rw-r--r--kernel/exit.c61
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:
666static void exit_mm(struct task_struct * tsk) 676static 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