mm: refactor vm_area_struct::anon_vma_name usage code
[linux-block.git] / kernel / fork.c
index d75a528f7b2196675c35a4c3ea8484eff88bddd2..f1e89007f22889c627aadb53934b27cd66b29afe 100644 (file)
@@ -366,14 +366,14 @@ struct vm_area_struct *vm_area_dup(struct vm_area_struct *orig)
                *new = data_race(*orig);
                INIT_LIST_HEAD(&new->anon_vma_chain);
                new->vm_next = new->vm_prev = NULL;
-               dup_vma_anon_name(orig, new);
+               dup_anon_vma_name(orig, new);
        }
        return new;
 }
 
 void vm_area_free(struct vm_area_struct *vma)
 {
-       free_vma_anon_name(vma);
+       free_anon_vma_name(vma);
        kmem_cache_free(vm_area_cachep, vma);
 }
 
@@ -2021,18 +2021,18 @@ static __latent_entropy struct task_struct *copy_process(
 #ifdef CONFIG_PROVE_LOCKING
        DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled);
 #endif
+       retval = copy_creds(p, clone_flags);
+       if (retval < 0)
+               goto bad_fork_free;
+
        retval = -EAGAIN;
        if (is_ucounts_overlimit(task_ucounts(p), UCOUNT_RLIMIT_NPROC, rlimit(RLIMIT_NPROC))) {
                if (p->real_cred->user != INIT_USER &&
                    !capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN))
-                       goto bad_fork_free;
+                       goto bad_fork_cleanup_count;
        }
        current->flags &= ~PF_NPROC_EXCEEDED;
 
-       retval = copy_creds(p, clone_flags);
-       if (retval < 0)
-               goto bad_fork_free;
-
        /*
         * If multiple threads are within copy_process(), then this check
         * triggers too late. This doesn't hurt, the check is only there
@@ -2266,6 +2266,17 @@ static __latent_entropy struct task_struct *copy_process(
        if (retval)
                goto bad_fork_put_pidfd;
 
+       /*
+        * Now that the cgroups are pinned, re-clone the parent cgroup and put
+        * the new task on the correct runqueue. All this *before* the task
+        * becomes visible.
+        *
+        * This isn't part of ->can_fork() because while the re-cloning is
+        * cgroup specific, it unconditionally needs to place the task on a
+        * runqueue.
+        */
+       sched_cgroup_fork(p, args);
+
        /*
         * From this point on we must avoid any synchronous user-space
         * communication until we take the tasklist-lock. In particular, we do
@@ -2323,10 +2334,6 @@ static __latent_entropy struct task_struct *copy_process(
                goto bad_fork_cancel_cgroup;
        }
 
-       /* past the last point of failure */
-       if (pidfile)
-               fd_install(pidfd, pidfile);
-
        init_task_pid_links(p);
        if (likely(p->pid)) {
                ptrace_init_task(p, (clone_flags & CLONE_PTRACE) || trace);
@@ -2375,8 +2382,11 @@ static __latent_entropy struct task_struct *copy_process(
        syscall_tracepoint_update(p);
        write_unlock_irq(&tasklist_lock);
 
+       if (pidfile)
+               fd_install(pidfd, pidfile);
+
        proc_fork_connector(p);
-       sched_post_fork(p, args);
+       sched_post_fork(p);
        cgroup_post_fork(p, args);
        perf_event_fork(p);