diff options
Diffstat (limited to 'kernel/fork.c')
| -rw-r--r-- | kernel/fork.c | 20 | 
1 files changed, 18 insertions, 2 deletions
diff --git a/kernel/fork.c b/kernel/fork.c index c060c7e7c247..623259fc794d 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -359,6 +359,12 @@ static inline void free_signal_struct(struct signal_struct *sig)  {  	taskstats_tgid_free(sig);  	sched_autogroup_exit(sig); +	/* +	 * __mmdrop is not safe to call from softirq context on x86 due to +	 * pgd_dtor so postpone it to the async context +	 */ +	if (sig->oom_mm) +		mmdrop_async(sig->oom_mm);  	kmem_cache_free(signal_cachep, sig);  } @@ -418,6 +424,7 @@ int arch_task_struct_size __read_mostly;  void __init fork_init(void)  { +	int i;  #ifndef CONFIG_ARCH_TASK_STRUCT_ALLOCATOR  #ifndef ARCH_MIN_TASKALIGN  #define ARCH_MIN_TASKALIGN	L1_CACHE_BYTES @@ -437,6 +444,10 @@ void __init fork_init(void)  	init_task.signal->rlim[RLIMIT_NPROC].rlim_max = max_threads/2;  	init_task.signal->rlim[RLIMIT_SIGPENDING] =  		init_task.signal->rlim[RLIMIT_NPROC]; + +	for (i = 0; i < UCOUNT_COUNTS; i++) { +		init_user_ns.ucount_max[i] = max_threads/2; +	}  }  int __weak arch_dup_task_struct(struct task_struct *dst, @@ -536,7 +547,8 @@ free_tsk:  }  #ifdef CONFIG_MMU -static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) +static __latent_entropy int dup_mmap(struct mm_struct *mm, +					struct mm_struct *oldmm)  {  	struct vm_area_struct *mpnt, *tmp, *prev, **pprev;  	struct rb_node **rb_link, *rb_parent; @@ -843,6 +855,7 @@ static inline void __mmput(struct mm_struct *mm)  	ksm_exit(mm);  	khugepaged_exit(mm); /* must run before exit_mmap */  	exit_mmap(mm); +	mm_put_huge_zero_page(mm);  	set_mm_exe_file(mm, NULL);  	if (!list_empty(&mm->mmlist)) {  		spin_lock(&mmlist_lock); @@ -851,6 +864,7 @@ static inline void __mmput(struct mm_struct *mm)  	}  	if (mm->binfmt)  		module_put(mm->binfmt->module); +	set_bit(MMF_OOM_SKIP, &mm->flags);  	mmdrop(mm);  } @@ -1428,7 +1442,8 @@ init_task_pid(struct task_struct *task, enum pid_type type, struct pid *pid)   * parts of the process environment (as per the clone   * flags). The actual kick-off is left to the caller.   */ -static struct task_struct *copy_process(unsigned long clone_flags, +static __latent_entropy struct task_struct *copy_process( +					unsigned long clone_flags,  					unsigned long stack_start,  					unsigned long stack_size,  					int __user *child_tidptr, @@ -1913,6 +1928,7 @@ long _do_fork(unsigned long clone_flags,  	p = copy_process(clone_flags, stack_start, stack_size,  			 child_tidptr, NULL, trace, tls, NUMA_NO_NODE); +	add_latent_entropy();  	/*  	 * Do this prior waking up the new thread - the thread pointer  	 * might get invalid after that point, if the thread exits quickly.  |