aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/fork.c
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2012-04-01 15:30:01 -0400
committerTejun Heo <tj@kernel.org>2012-04-01 15:55:00 -0400
commit959d851caa48829eb85cb85aa949fd6b4c5d5bc6 (patch)
tree3ba9c94ec346275fb44c4f0d1cd2537cdff8d811 /kernel/fork.c
parenta5567932fc926739e29e98487128080f40c61710 (diff)
parent48ddbe194623ae089cc0576e60363f2d2e85662a (diff)
Merge branch 'for-3.5' of ../cgroup into block/for-3.5/core-merged
cgroup/for-3.5 contains the following changes which blk-cgroup needs to proceed with the on-going cleanup. * Dynamic addition and removal of cftypes to make config/stat file handling modular for policies. * cgroup removal update to not wait for css references to drain to fix blkcg removal hang caused by cfq caching cfqgs. Pull in cgroup/for-3.5 into block/for-3.5/core. This causes the following conflicts in block/blk-cgroup.c. * 761b3ef50e "cgroup: remove cgroup_subsys argument from callbacks" conflicts with blkiocg_pre_destroy() addition and blkiocg_attach() removal. Resolved by removing @subsys from all subsys methods. * 676f7c8f84 "cgroup: relocate cftype and cgroup_subsys definitions in controllers" conflicts with ->pre_destroy() and ->attach() updates and removal of modular config. Resolved by dropping forward declarations of the methods and applying updates to the relocated blkio_subsys. * 4baf6e3325 "cgroup: convert all non-memcg controllers to the new cftype interface" builds upon the previous item. Resolved by adding ->base_cftypes to the relocated blkio_subsys. Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'kernel/fork.c')
-rw-r--r--kernel/fork.c101
1 files changed, 74 insertions, 27 deletions
diff --git a/kernel/fork.c b/kernel/fork.c
index a1b632713e43..08eb8584e2a8 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -66,6 +66,7 @@
66#include <linux/user-return-notifier.h> 66#include <linux/user-return-notifier.h>
67#include <linux/oom.h> 67#include <linux/oom.h>
68#include <linux/khugepaged.h> 68#include <linux/khugepaged.h>
69#include <linux/signalfd.h>
69 70
70#include <asm/pgtable.h> 71#include <asm/pgtable.h>
71#include <asm/pgalloc.h> 72#include <asm/pgalloc.h>
@@ -192,6 +193,7 @@ void __put_task_struct(struct task_struct *tsk)
192 WARN_ON(atomic_read(&tsk->usage)); 193 WARN_ON(atomic_read(&tsk->usage));
193 WARN_ON(tsk == current); 194 WARN_ON(tsk == current);
194 195
196 security_task_free(tsk);
195 exit_creds(tsk); 197 exit_creds(tsk);
196 delayacct_tsk_free(tsk); 198 delayacct_tsk_free(tsk);
197 put_signal_struct(tsk->signal); 199 put_signal_struct(tsk->signal);
@@ -354,7 +356,7 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
354 charge = 0; 356 charge = 0;
355 if (mpnt->vm_flags & VM_ACCOUNT) { 357 if (mpnt->vm_flags & VM_ACCOUNT) {
356 unsigned int len = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT; 358 unsigned int len = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT;
357 if (security_vm_enough_memory(len)) 359 if (security_vm_enough_memory_mm(oldmm, len)) /* sic */
358 goto fail_nomem; 360 goto fail_nomem;
359 charge = len; 361 charge = len;
360 } 362 }
@@ -510,6 +512,23 @@ static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p)
510 return NULL; 512 return NULL;
511} 513}
512 514
515static void check_mm(struct mm_struct *mm)
516{
517 int i;
518
519 for (i = 0; i < NR_MM_COUNTERS; i++) {
520 long x = atomic_long_read(&mm->rss_stat.count[i]);
521
522 if (unlikely(x))
523 printk(KERN_ALERT "BUG: Bad rss-counter state "
524 "mm:%p idx:%d val:%ld\n", mm, i, x);
525 }
526
527#ifdef CONFIG_TRANSPARENT_HUGEPAGE
528 VM_BUG_ON(mm->pmd_huge_pte);
529#endif
530}
531
513/* 532/*
514 * Allocate and initialize an mm_struct. 533 * Allocate and initialize an mm_struct.
515 */ 534 */
@@ -537,9 +556,7 @@ void __mmdrop(struct mm_struct *mm)
537 mm_free_pgd(mm); 556 mm_free_pgd(mm);
538 destroy_context(mm); 557 destroy_context(mm);
539 mmu_notifier_mm_destroy(mm); 558 mmu_notifier_mm_destroy(mm);
540#ifdef CONFIG_TRANSPARENT_HUGEPAGE 559 check_mm(mm);
541 VM_BUG_ON(mm->pmd_huge_pte);
542#endif
543 free_mm(mm); 560 free_mm(mm);
544} 561}
545EXPORT_SYMBOL_GPL(__mmdrop); 562EXPORT_SYMBOL_GPL(__mmdrop);
@@ -667,6 +684,38 @@ struct mm_struct *mm_access(struct task_struct *task, unsigned int mode)
667 return mm; 684 return mm;
668} 685}
669 686
687static void complete_vfork_done(struct task_struct *tsk)
688{
689 struct completion *vfork;
690
691 task_lock(tsk);
692 vfork = tsk->vfork_done;
693 if (likely(vfork)) {
694 tsk->vfork_done = NULL;
695 complete(vfork);
696 }
697 task_unlock(tsk);
698}
699
700static int wait_for_vfork_done(struct task_struct *child,
701 struct completion *vfork)
702{
703 int killed;
704
705 freezer_do_not_count();
706 killed = wait_for_completion_killable(vfork);
707 freezer_count();
708
709 if (killed) {
710 task_lock(child);
711 child->vfork_done = NULL;
712 task_unlock(child);
713 }
714
715 put_task_struct(child);
716 return killed;
717}
718
670/* Please note the differences between mmput and mm_release. 719/* Please note the differences between mmput and mm_release.
671 * mmput is called whenever we stop holding onto a mm_struct, 720 * mmput is called whenever we stop holding onto a mm_struct,
672 * error success whatever. 721 * error success whatever.
@@ -682,8 +731,6 @@ struct mm_struct *mm_access(struct task_struct *task, unsigned int mode)
682 */ 731 */
683void mm_release(struct task_struct *tsk, struct mm_struct *mm) 732void mm_release(struct task_struct *tsk, struct mm_struct *mm)
684{ 733{
685 struct completion *vfork_done = tsk->vfork_done;
686
687 /* Get rid of any futexes when releasing the mm */ 734 /* Get rid of any futexes when releasing the mm */
688#ifdef CONFIG_FUTEX 735#ifdef CONFIG_FUTEX
689 if (unlikely(tsk->robust_list)) { 736 if (unlikely(tsk->robust_list)) {
@@ -703,17 +750,15 @@ void mm_release(struct task_struct *tsk, struct mm_struct *mm)
703 /* Get rid of any cached register state */ 750 /* Get rid of any cached register state */
704 deactivate_mm(tsk, mm); 751 deactivate_mm(tsk, mm);
705 752
706 /* notify parent sleeping on vfork() */ 753 if (tsk->vfork_done)
707 if (vfork_done) { 754 complete_vfork_done(tsk);
708 tsk->vfork_done = NULL;
709 complete(vfork_done);
710 }
711 755
712 /* 756 /*
713 * If we're exiting normally, clear a user-space tid field if 757 * If we're exiting normally, clear a user-space tid field if
714 * requested. We leave this alone when dying by signal, to leave 758 * requested. We leave this alone when dying by signal, to leave
715 * the value intact in a core dump, and to save the unnecessary 759 * the value intact in a core dump, and to save the unnecessary
716 * trouble otherwise. Userland only wants this done for a sys_exit. 760 * trouble, say, a killed vfork parent shouldn't touch this mm.
761 * Userland only wants this done for a sys_exit.
717 */ 762 */
718 if (tsk->clear_child_tid) { 763 if (tsk->clear_child_tid) {
719 if (!(tsk->flags & PF_SIGNALED) && 764 if (!(tsk->flags & PF_SIGNALED) &&
@@ -934,8 +979,10 @@ static int copy_sighand(unsigned long clone_flags, struct task_struct *tsk)
934 979
935void __cleanup_sighand(struct sighand_struct *sighand) 980void __cleanup_sighand(struct sighand_struct *sighand)
936{ 981{
937 if (atomic_dec_and_test(&sighand->count)) 982 if (atomic_dec_and_test(&sighand->count)) {
983 signalfd_cleanup(sighand);
938 kmem_cache_free(sighand_cachep, sighand); 984 kmem_cache_free(sighand_cachep, sighand);
985 }
939} 986}
940 987
941 988
@@ -1003,6 +1050,9 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
1003 sig->oom_score_adj = current->signal->oom_score_adj; 1050 sig->oom_score_adj = current->signal->oom_score_adj;
1004 sig->oom_score_adj_min = current->signal->oom_score_adj_min; 1051 sig->oom_score_adj_min = current->signal->oom_score_adj_min;
1005 1052
1053 sig->has_child_subreaper = current->signal->has_child_subreaper ||
1054 current->signal->is_child_subreaper;
1055
1006 mutex_init(&sig->cred_guard_mutex); 1056 mutex_init(&sig->cred_guard_mutex);
1007 1057
1008 return 0; 1058 return 0;
@@ -1014,7 +1064,6 @@ static void copy_flags(unsigned long clone_flags, struct task_struct *p)
1014 1064
1015 new_flags &= ~(PF_SUPERPRIV | PF_WQ_WORKER); 1065 new_flags &= ~(PF_SUPERPRIV | PF_WQ_WORKER);
1016 new_flags |= PF_FORKNOEXEC; 1066 new_flags |= PF_FORKNOEXEC;
1017 new_flags |= PF_STARTING;
1018 p->flags = new_flags; 1067 p->flags = new_flags;
1019} 1068}
1020 1069
@@ -1191,6 +1240,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
1191#ifdef CONFIG_CPUSETS 1240#ifdef CONFIG_CPUSETS
1192 p->cpuset_mem_spread_rotor = NUMA_NO_NODE; 1241 p->cpuset_mem_spread_rotor = NUMA_NO_NODE;
1193 p->cpuset_slab_spread_rotor = NUMA_NO_NODE; 1242 p->cpuset_slab_spread_rotor = NUMA_NO_NODE;
1243 seqcount_init(&p->mems_allowed_seq);
1194#endif 1244#endif
1195#ifdef CONFIG_TRACE_IRQFLAGS 1245#ifdef CONFIG_TRACE_IRQFLAGS
1196 p->irq_events = 0; 1246 p->irq_events = 0;
@@ -1309,7 +1359,13 @@ static struct task_struct *copy_process(unsigned long clone_flags,
1309 clear_all_latency_tracing(p); 1359 clear_all_latency_tracing(p);
1310 1360
1311 /* ok, now we should be set up.. */ 1361 /* ok, now we should be set up.. */
1312 p->exit_signal = (clone_flags & CLONE_THREAD) ? -1 : (clone_flags & CSIGNAL); 1362 if (clone_flags & CLONE_THREAD)
1363 p->exit_signal = -1;
1364 else if (clone_flags & CLONE_PARENT)
1365 p->exit_signal = current->group_leader->exit_signal;
1366 else
1367 p->exit_signal = (clone_flags & CSIGNAL);
1368
1313 p->pdeath_signal = 0; 1369 p->pdeath_signal = 0;
1314 p->exit_state = 0; 1370 p->exit_state = 0;
1315 1371
@@ -1544,16 +1600,9 @@ long do_fork(unsigned long clone_flags,
1544 if (clone_flags & CLONE_VFORK) { 1600 if (clone_flags & CLONE_VFORK) {
1545 p->vfork_done = &vfork; 1601 p->vfork_done = &vfork;
1546 init_completion(&vfork); 1602 init_completion(&vfork);
1603 get_task_struct(p);
1547 } 1604 }
1548 1605
1549 /*
1550 * We set PF_STARTING at creation in case tracing wants to
1551 * use this to distinguish a fully live task from one that
1552 * hasn't finished SIGSTOP raising yet. Now we clear it
1553 * and set the child going.
1554 */
1555 p->flags &= ~PF_STARTING;
1556
1557 wake_up_new_task(p); 1606 wake_up_new_task(p);
1558 1607
1559 /* forking complete and child started to run, tell ptracer */ 1608 /* forking complete and child started to run, tell ptracer */
@@ -1561,10 +1610,8 @@ long do_fork(unsigned long clone_flags,
1561 ptrace_event(trace, nr); 1610 ptrace_event(trace, nr);
1562 1611
1563 if (clone_flags & CLONE_VFORK) { 1612 if (clone_flags & CLONE_VFORK) {
1564 freezer_do_not_count(); 1613 if (!wait_for_vfork_done(p, &vfork))
1565 wait_for_completion(&vfork); 1614 ptrace_event(PTRACE_EVENT_VFORK_DONE, nr);
1566 freezer_count();
1567 ptrace_event(PTRACE_EVENT_VFORK_DONE, nr);
1568 } 1615 }
1569 } else { 1616 } else {
1570 nr = PTR_ERR(p); 1617 nr = PTR_ERR(p);