]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - kernel/fork.c
Merge tag 'tty-5.0-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
[linux.git] / kernel / fork.c
index 07cddff89c7b6bac3658c8cb41dd32dc64a3cfa4..b69248e6f0e024c0407df16dfdc8a4919b590c78 100644 (file)
@@ -164,10 +164,6 @@ static inline void free_task_struct(struct task_struct *tsk)
 }
 #endif
 
-void __weak arch_release_thread_stack(unsigned long *stack)
-{
-}
-
 #ifndef CONFIG_ARCH_THREAD_STACK_ALLOCATOR
 
 /*
@@ -221,6 +217,7 @@ static unsigned long *alloc_thread_stack_node(struct task_struct *tsk, int node)
                memset(s->addr, 0, THREAD_SIZE);
 
                tsk->stack_vm_area = s;
+               tsk->stack = s->addr;
                return s->addr;
        }
 
@@ -240,8 +237,10 @@ static unsigned long *alloc_thread_stack_node(struct task_struct *tsk, int node)
         * free_thread_stack() can be called in interrupt context,
         * so cache the vm_struct.
         */
-       if (stack)
+       if (stack) {
                tsk->stack_vm_area = find_vm_area(stack);
+               tsk->stack = stack;
+       }
        return stack;
 #else
        struct page *page = alloc_pages_node(node, THREADINFO_GFP,
@@ -288,7 +287,10 @@ static struct kmem_cache *thread_stack_cache;
 static unsigned long *alloc_thread_stack_node(struct task_struct *tsk,
                                                  int node)
 {
-       return kmem_cache_alloc_node(thread_stack_cache, THREADINFO_GFP, node);
+       unsigned long *stack;
+       stack = kmem_cache_alloc_node(thread_stack_cache, THREADINFO_GFP, node);
+       tsk->stack = stack;
+       return stack;
 }
 
 static void free_thread_stack(struct task_struct *tsk)
@@ -417,7 +419,6 @@ static void release_task_stack(struct task_struct *tsk)
                return;  /* Better to leak the stack than to free prematurely */
 
        account_kernel_stack(tsk, -1);
-       arch_release_thread_stack(tsk->stack);
        free_thread_stack(tsk);
        tsk->stack = NULL;
 #ifdef CONFIG_VMAP_STACK
@@ -739,15 +740,16 @@ void __init __weak arch_task_cache_init(void) { }
 static void set_max_threads(unsigned int max_threads_suggested)
 {
        u64 threads;
+       unsigned long nr_pages = totalram_pages();
 
        /*
         * The number of threads shall be limited such that the thread
         * structures may only consume a small part of the available memory.
         */
-       if (fls64(totalram_pages) + fls64(PAGE_SIZE) > 64)
+       if (fls64(nr_pages) + fls64(PAGE_SIZE) > 64)
                threads = MAX_THREADS;
        else
-               threads = div64_u64((u64) totalram_pages * (u64) PAGE_SIZE,
+               threads = div64_u64((u64) nr_pages * (u64) PAGE_SIZE,
                                    (u64) THREAD_SIZE * 8UL);
 
        if (threads > max_threads_suggested)
@@ -835,7 +837,7 @@ static struct task_struct *dup_task_struct(struct task_struct *orig, int node)
 {
        struct task_struct *tsk;
        unsigned long *stack;
-       struct vm_struct *stack_vm_area;
+       struct vm_struct *stack_vm_area __maybe_unused;
        int err;
 
        if (node == NUMA_NO_NODE)
@@ -1832,8 +1834,6 @@ static __latent_entropy struct task_struct *copy_process(
 
        posix_cpu_timers_init(p);
 
-       p->start_time = ktime_get_ns();
-       p->real_start_time = ktime_get_boot_ns();
        p->io_context = NULL;
        audit_set_context(p, NULL);
        cgroup_fork(p);
@@ -1999,6 +1999,17 @@ static __latent_entropy struct task_struct *copy_process(
        if (retval)
                goto bad_fork_free_pid;
 
+       /*
+        * From this point on we must avoid any synchronous user-space
+        * communication until we take the tasklist-lock. In particular, we do
+        * not want user-space to be able to predict the process start-time by
+        * stalling fork(2) after we recorded the start_time but before it is
+        * visible to the system.
+        */
+
+       p->start_time = ktime_get_ns();
+       p->real_start_time = ktime_get_boot_ns();
+
        /*
         * Make it visible to the rest of the system, but dont wake it up yet.
         * Need tasklist lock for parent etc handling!