aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/fork.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/fork.c')
-rw-r--r--kernel/fork.c93
1 files changed, 45 insertions, 48 deletions
diff --git a/kernel/fork.c b/kernel/fork.c
index 6715ebc3761d..b9e2edd00726 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -60,6 +60,7 @@
60#include <linux/tty.h> 60#include <linux/tty.h>
61#include <linux/proc_fs.h> 61#include <linux/proc_fs.h>
62#include <linux/blkdev.h> 62#include <linux/blkdev.h>
63#include <linux/fs_struct.h>
63#include <trace/sched.h> 64#include <trace/sched.h>
64#include <linux/magic.h> 65#include <linux/magic.h>
65 66
@@ -284,7 +285,7 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
284 mm->free_area_cache = oldmm->mmap_base; 285 mm->free_area_cache = oldmm->mmap_base;
285 mm->cached_hole_size = ~0UL; 286 mm->cached_hole_size = ~0UL;
286 mm->map_count = 0; 287 mm->map_count = 0;
287 cpus_clear(mm->cpu_vm_mask); 288 cpumask_clear(mm_cpumask(mm));
288 mm->mm_rb = RB_ROOT; 289 mm->mm_rb = RB_ROOT;
289 rb_link = &mm->mm_rb.rb_node; 290 rb_link = &mm->mm_rb.rb_node;
290 rb_parent = NULL; 291 rb_parent = NULL;
@@ -644,6 +645,9 @@ static int copy_mm(unsigned long clone_flags, struct task_struct * tsk)
644 645
645 tsk->min_flt = tsk->maj_flt = 0; 646 tsk->min_flt = tsk->maj_flt = 0;
646 tsk->nvcsw = tsk->nivcsw = 0; 647 tsk->nvcsw = tsk->nivcsw = 0;
648#ifdef CONFIG_DETECT_HUNG_TASK
649 tsk->last_switch_count = tsk->nvcsw + tsk->nivcsw;
650#endif
647 651
648 tsk->mm = NULL; 652 tsk->mm = NULL;
649 tsk->active_mm = NULL; 653 tsk->active_mm = NULL;
@@ -681,38 +685,21 @@ fail_nomem:
681 return retval; 685 return retval;
682} 686}
683 687
684static struct fs_struct *__copy_fs_struct(struct fs_struct *old)
685{
686 struct fs_struct *fs = kmem_cache_alloc(fs_cachep, GFP_KERNEL);
687 /* We don't need to lock fs - think why ;-) */
688 if (fs) {
689 atomic_set(&fs->count, 1);
690 rwlock_init(&fs->lock);
691 fs->umask = old->umask;
692 read_lock(&old->lock);
693 fs->root = old->root;
694 path_get(&old->root);
695 fs->pwd = old->pwd;
696 path_get(&old->pwd);
697 read_unlock(&old->lock);
698 }
699 return fs;
700}
701
702struct fs_struct *copy_fs_struct(struct fs_struct *old)
703{
704 return __copy_fs_struct(old);
705}
706
707EXPORT_SYMBOL_GPL(copy_fs_struct);
708
709static int copy_fs(unsigned long clone_flags, struct task_struct *tsk) 688static int copy_fs(unsigned long clone_flags, struct task_struct *tsk)
710{ 689{
690 struct fs_struct *fs = current->fs;
711 if (clone_flags & CLONE_FS) { 691 if (clone_flags & CLONE_FS) {
712 atomic_inc(&current->fs->count); 692 /* tsk->fs is already what we want */
693 write_lock(&fs->lock);
694 if (fs->in_exec) {
695 write_unlock(&fs->lock);
696 return -EAGAIN;
697 }
698 fs->users++;
699 write_unlock(&fs->lock);
713 return 0; 700 return 0;
714 } 701 }
715 tsk->fs = __copy_fs_struct(current->fs); 702 tsk->fs = copy_fs_struct(fs);
716 if (!tsk->fs) 703 if (!tsk->fs)
717 return -ENOMEM; 704 return -ENOMEM;
718 return 0; 705 return 0;
@@ -813,6 +800,12 @@ static void posix_cpu_timers_init_group(struct signal_struct *sig)
813 sig->cputime_expires.virt_exp = cputime_zero; 800 sig->cputime_expires.virt_exp = cputime_zero;
814 sig->cputime_expires.sched_exp = 0; 801 sig->cputime_expires.sched_exp = 0;
815 802
803 if (sig->rlim[RLIMIT_CPU].rlim_cur != RLIM_INFINITY) {
804 sig->cputime_expires.prof_exp =
805 secs_to_cputime(sig->rlim[RLIMIT_CPU].rlim_cur);
806 sig->cputimer.running = 1;
807 }
808
816 /* The timer lists. */ 809 /* The timer lists. */
817 INIT_LIST_HEAD(&sig->cpu_timers[0]); 810 INIT_LIST_HEAD(&sig->cpu_timers[0]);
818 INIT_LIST_HEAD(&sig->cpu_timers[1]); 811 INIT_LIST_HEAD(&sig->cpu_timers[1]);
@@ -828,11 +821,8 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
828 atomic_inc(&current->signal->live); 821 atomic_inc(&current->signal->live);
829 return 0; 822 return 0;
830 } 823 }
831 sig = kmem_cache_alloc(signal_cachep, GFP_KERNEL);
832
833 if (sig)
834 posix_cpu_timers_init_group(sig);
835 824
825 sig = kmem_cache_alloc(signal_cachep, GFP_KERNEL);
836 tsk->signal = sig; 826 tsk->signal = sig;
837 if (!sig) 827 if (!sig)
838 return -ENOMEM; 828 return -ENOMEM;
@@ -841,6 +831,8 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
841 atomic_set(&sig->live, 1); 831 atomic_set(&sig->live, 1);
842 init_waitqueue_head(&sig->wait_chldexit); 832 init_waitqueue_head(&sig->wait_chldexit);
843 sig->flags = 0; 833 sig->flags = 0;
834 if (clone_flags & CLONE_NEWPID)
835 sig->flags |= SIGNAL_UNKILLABLE;
844 sig->group_exit_code = 0; 836 sig->group_exit_code = 0;
845 sig->group_exit_task = NULL; 837 sig->group_exit_task = NULL;
846 sig->group_stop_count = 0; 838 sig->group_stop_count = 0;
@@ -870,6 +862,8 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
870 memcpy(sig->rlim, current->signal->rlim, sizeof sig->rlim); 862 memcpy(sig->rlim, current->signal->rlim, sizeof sig->rlim);
871 task_unlock(current->group_leader); 863 task_unlock(current->group_leader);
872 864
865 posix_cpu_timers_init_group(sig);
866
873 acct_init_pacct(&sig->pacct); 867 acct_init_pacct(&sig->pacct);
874 868
875 tty_audit_fork(sig); 869 tty_audit_fork(sig);
@@ -1046,11 +1040,6 @@ static struct task_struct *copy_process(unsigned long clone_flags,
1046 1040
1047 p->default_timer_slack_ns = current->timer_slack_ns; 1041 p->default_timer_slack_ns = current->timer_slack_ns;
1048 1042
1049#ifdef CONFIG_DETECT_SOFTLOCKUP
1050 p->last_switch_count = 0;
1051 p->last_switch_timestamp = 0;
1052#endif
1053
1054 task_io_accounting_init(&p->ioac); 1043 task_io_accounting_init(&p->ioac);
1055 acct_clear_integrals(p); 1044 acct_clear_integrals(p);
1056 1045
@@ -1125,7 +1114,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
1125 goto bad_fork_cleanup_mm; 1114 goto bad_fork_cleanup_mm;
1126 if ((retval = copy_io(clone_flags, p))) 1115 if ((retval = copy_io(clone_flags, p)))
1127 goto bad_fork_cleanup_namespaces; 1116 goto bad_fork_cleanup_namespaces;
1128 retval = copy_thread(0, clone_flags, stack_start, stack_size, p, regs); 1117 retval = copy_thread(clone_flags, stack_start, stack_size, p, regs);
1129 if (retval) 1118 if (retval)
1130 goto bad_fork_cleanup_io; 1119 goto bad_fork_cleanup_io;
1131 1120
@@ -1263,8 +1252,6 @@ static struct task_struct *copy_process(unsigned long clone_flags,
1263 p->signal->leader_pid = pid; 1252 p->signal->leader_pid = pid;
1264 tty_kref_put(p->signal->tty); 1253 tty_kref_put(p->signal->tty);
1265 p->signal->tty = tty_kref_get(current->signal->tty); 1254 p->signal->tty = tty_kref_get(current->signal->tty);
1266 set_task_pgrp(p, task_pgrp_nr(current));
1267 set_task_session(p, task_session_nr(current));
1268 attach_pid(p, PIDTYPE_PGID, task_pgrp(current)); 1255 attach_pid(p, PIDTYPE_PGID, task_pgrp(current));
1269 attach_pid(p, PIDTYPE_SID, task_session(current)); 1256 attach_pid(p, PIDTYPE_SID, task_session(current));
1270 list_add_tail_rcu(&p->tasks, &init_task.tasks); 1257 list_add_tail_rcu(&p->tasks, &init_task.tasks);
@@ -1488,6 +1475,7 @@ void __init proc_caches_init(void)
1488 mm_cachep = kmem_cache_create("mm_struct", 1475 mm_cachep = kmem_cache_create("mm_struct",
1489 sizeof(struct mm_struct), ARCH_MIN_MMSTRUCT_ALIGN, 1476 sizeof(struct mm_struct), ARCH_MIN_MMSTRUCT_ALIGN,
1490 SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL); 1477 SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
1478 vm_area_cachep = KMEM_CACHE(vm_area_struct, SLAB_PANIC);
1491 mmap_init(); 1479 mmap_init();
1492} 1480}
1493 1481
@@ -1543,12 +1531,16 @@ static int unshare_fs(unsigned long unshare_flags, struct fs_struct **new_fsp)
1543{ 1531{
1544 struct fs_struct *fs = current->fs; 1532 struct fs_struct *fs = current->fs;
1545 1533
1546 if ((unshare_flags & CLONE_FS) && 1534 if (!(unshare_flags & CLONE_FS) || !fs)
1547 (fs && atomic_read(&fs->count) > 1)) { 1535 return 0;
1548 *new_fsp = __copy_fs_struct(current->fs); 1536
1549 if (!*new_fsp) 1537 /* don't need lock here; in the worst case we'll do useless copy */
1550 return -ENOMEM; 1538 if (fs->users == 1)
1551 } 1539 return 0;
1540
1541 *new_fsp = copy_fs_struct(fs);
1542 if (!*new_fsp)
1543 return -ENOMEM;
1552 1544
1553 return 0; 1545 return 0;
1554} 1546}
@@ -1664,8 +1656,13 @@ SYSCALL_DEFINE1(unshare, unsigned long, unshare_flags)
1664 1656
1665 if (new_fs) { 1657 if (new_fs) {
1666 fs = current->fs; 1658 fs = current->fs;
1659 write_lock(&fs->lock);
1667 current->fs = new_fs; 1660 current->fs = new_fs;
1668 new_fs = fs; 1661 if (--fs->users)
1662 new_fs = NULL;
1663 else
1664 new_fs = fs;
1665 write_unlock(&fs->lock);
1669 } 1666 }
1670 1667
1671 if (new_mm) { 1668 if (new_mm) {
@@ -1704,7 +1701,7 @@ bad_unshare_cleanup_sigh:
1704 1701
1705bad_unshare_cleanup_fs: 1702bad_unshare_cleanup_fs:
1706 if (new_fs) 1703 if (new_fs)
1707 put_fs_struct(new_fs); 1704 free_fs_struct(new_fs);
1708 1705
1709bad_unshare_cleanup_thread: 1706bad_unshare_cleanup_thread:
1710bad_unshare_out: 1707bad_unshare_out: