signals: s/siginitset/sigemptyset/ in do_sigtimedwait()
[firefly-linux-kernel-4.4.55.git] / kernel / fork.c
index 332688e5e7b4c93e55f3785ceb6beb70f4b2182f..d2799d1fc952757270f791901394ed2b9f10062b 100644 (file)
@@ -28,6 +28,8 @@
 #include <linux/mman.h>
 #include <linux/mmu_notifier.h>
 #include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/vmacache.h>
 #include <linux/nsproxy.h>
 #include <linux/capability.h>
 #include <linux/cpu.h>
@@ -71,6 +73,7 @@
 #include <linux/signalfd.h>
 #include <linux/uprobes.h>
 #include <linux/aio.h>
+#include <linux/compiler.h>
 
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
@@ -147,15 +150,15 @@ void __weak arch_release_thread_info(struct thread_info *ti)
 static struct thread_info *alloc_thread_info_node(struct task_struct *tsk,
                                                  int node)
 {
-       struct page *page = alloc_pages_node(node, THREADINFO_GFP_ACCOUNTED,
-                                            THREAD_SIZE_ORDER);
+       struct page *page = alloc_kmem_pages_node(node, THREADINFO_GFP,
+                                                 THREAD_SIZE_ORDER);
 
        return page ? page_address(page) : NULL;
 }
 
 static inline void free_thread_info(struct thread_info *ti)
 {
-       free_memcg_kmem_pages((unsigned long)ti, THREAD_SIZE_ORDER);
+       free_kmem_pages((unsigned long)ti, THREAD_SIZE_ORDER);
 }
 # else
 static struct kmem_cache *thread_info_cache;
@@ -284,7 +287,7 @@ void __init fork_init(unsigned long mempages)
                init_task.signal->rlim[RLIMIT_NPROC];
 }
 
-int __attribute__((weak)) arch_dup_task_struct(struct task_struct *dst,
+int __weak arch_dup_task_struct(struct task_struct *dst,
                                               struct task_struct *src)
 {
        *dst = *src;
@@ -364,7 +367,7 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
 
        mm->locked_vm = 0;
        mm->mmap = NULL;
-       mm->mmap_cache = NULL;
+       mm->vmacache_seqnum = 0;
        mm->map_count = 0;
        cpumask_clear(mm_cpumask(mm));
        mm->mm_rb = RB_ROOT;
@@ -530,8 +533,6 @@ static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p)
        atomic_set(&mm->mm_count, 1);
        init_rwsem(&mm->mmap_sem);
        INIT_LIST_HEAD(&mm->mmlist);
-       mm->flags = (current->mm) ?
-               (current->mm->flags & MMF_INIT_MASK) : default_dump_filter;
        mm->core_state = NULL;
        atomic_long_set(&mm->nr_ptes, 0);
        memset(&mm->rss_stat, 0, sizeof(mm->rss_stat));
@@ -540,8 +541,15 @@ static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p)
        mm_init_owner(mm, p);
        clear_tlb_flush_pending(mm);
 
-       if (likely(!mm_alloc_pgd(mm))) {
+       if (current->mm) {
+               mm->flags = current->mm->flags & MMF_INIT_MASK;
+               mm->def_flags = current->mm->def_flags & VM_INIT_DEF_MASK;
+       } else {
+               mm->flags = default_dump_filter;
                mm->def_flags = 0;
+       }
+
+       if (likely(!mm_alloc_pgd(mm))) {
                mmu_notifier_mm_init(mm);
                return mm;
        }
@@ -877,6 +885,9 @@ static int copy_mm(unsigned long clone_flags, struct task_struct *tsk)
        if (!oldmm)
                return 0;
 
+       /* initialize the new vmacache entries */
+       vmacache_flush(tsk);
+
        if (clone_flags & CLONE_VM) {
                atomic_inc(&oldmm->mm_users);
                mm = oldmm;
@@ -1070,15 +1081,6 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
        return 0;
 }
 
-static void copy_flags(unsigned long clone_flags, struct task_struct *p)
-{
-       unsigned long new_flags = p->flags;
-
-       new_flags &= ~(PF_SUPERPRIV | PF_WQ_WORKER);
-       new_flags |= PF_FORKNOEXEC;
-       p->flags = new_flags;
-}
-
 SYSCALL_DEFINE1(set_tid_address, int __user *, tidptr)
 {
        current->clear_child_tid = tidptr;
@@ -1097,12 +1099,12 @@ static void rt_mutex_init_task(struct task_struct *p)
 #endif
 }
 
-#ifdef CONFIG_MM_OWNER
+#ifdef CONFIG_MEMCG
 void mm_init_owner(struct mm_struct *mm, struct task_struct *p)
 {
        mm->owner = p;
 }
-#endif /* CONFIG_MM_OWNER */
+#endif /* CONFIG_MEMCG */
 
 /*
  * Initialize POSIX timer handling for a single task.
@@ -1228,7 +1230,8 @@ static struct task_struct *copy_process(unsigned long clone_flags,
                goto bad_fork_cleanup_count;
 
        delayacct_tsk_init(p);  /* Must remain after dup_task_struct() */
-       copy_flags(clone_flags, p);
+       p->flags &= ~(PF_SUPERPRIV | PF_WQ_WORKER);
+       p->flags |= PF_FORKNOEXEC;
        INIT_LIST_HEAD(&p->children);
        INIT_LIST_HEAD(&p->sibling);
        rcu_copy_process(p);
@@ -1272,9 +1275,8 @@ static struct task_struct *copy_process(unsigned long clone_flags,
        if (IS_ERR(p->mempolicy)) {
                retval = PTR_ERR(p->mempolicy);
                p->mempolicy = NULL;
-               goto bad_fork_cleanup_cgroup;
+               goto bad_fork_cleanup_threadgroup_lock;
        }
-       mpol_fix_fork_child_flag(p);
 #endif
 #ifdef CONFIG_CPUSETS
        p->cpuset_mem_spread_rotor = NUMA_NO_NODE;
@@ -1525,11 +1527,10 @@ bad_fork_cleanup_policy:
        perf_event_free_task(p);
 #ifdef CONFIG_NUMA
        mpol_put(p->mempolicy);
-bad_fork_cleanup_cgroup:
+bad_fork_cleanup_threadgroup_lock:
 #endif
        if (clone_flags & CLONE_THREAD)
                threadgroup_change_end(current);
-       cgroup_exit(p, 0);
        delayacct_tsk_free(p);
        module_put(task_thread_info(p)->exec_domain->module);
 bad_fork_cleanup_count:
@@ -1605,10 +1606,12 @@ long do_fork(unsigned long clone_flags,
         */
        if (!IS_ERR(p)) {
                struct completion vfork;
+               struct pid *pid;
 
                trace_sched_process_fork(current, p);
 
-               nr = task_pid_vnr(p);
+               pid = get_task_pid(p, PIDTYPE_PID);
+               nr = pid_vnr(pid);
 
                if (clone_flags & CLONE_PARENT_SETTID)
                        put_user(nr, parent_tidptr);
@@ -1623,12 +1626,14 @@ long do_fork(unsigned long clone_flags,
 
                /* forking complete and child started to run, tell ptracer */
                if (unlikely(trace))
-                       ptrace_event(trace, nr);
+                       ptrace_event_pid(trace, pid);
 
                if (clone_flags & CLONE_VFORK) {
                        if (!wait_for_vfork_done(p, &vfork))
-                               ptrace_event(PTRACE_EVENT_VFORK_DONE, nr);
+                               ptrace_event_pid(PTRACE_EVENT_VFORK_DONE, pid);
                }
+
+               put_pid(pid);
        } else {
                nr = PTR_ERR(p);
        }