diff options
Diffstat (limited to 'kernel/fork.c')
| -rw-r--r-- | kernel/fork.c | 28 | 
1 files changed, 12 insertions, 16 deletions
diff --git a/kernel/fork.c b/kernel/fork.c index 47b4e4f379f..ab5211b9e62 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -386,7 +386,8 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)  		}  		charge = 0;  		if (mpnt->vm_flags & VM_ACCOUNT) { -			unsigned int len = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT; +			unsigned long len; +			len = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT;  			if (security_vm_enough_memory_mm(oldmm, len)) /* sic */  				goto fail_nomem;  			charge = len; @@ -614,7 +615,6 @@ void mmput(struct mm_struct *mm)  			list_del(&mm->mmlist);  			spin_unlock(&mmlist_lock);  		} -		put_swap_token(mm);  		if (mm->binfmt)  			module_put(mm->binfmt->module);  		mmdrop(mm); @@ -787,9 +787,6 @@ void mm_release(struct task_struct *tsk, struct mm_struct *mm)  	/* Get rid of any cached register state */  	deactivate_mm(tsk, mm); -	if (tsk->vfork_done) -		complete_vfork_done(tsk); -  	/*  	 * If we're exiting normally, clear a user-space tid field if  	 * requested.  We leave this alone when dying by signal, to leave @@ -810,6 +807,13 @@ void mm_release(struct task_struct *tsk, struct mm_struct *mm)  		}  		tsk->clear_child_tid = NULL;  	} + +	/* +	 * All done, finally we can wake up parent and return this mm to him. +	 * Also kthread_stop() uses this completion for synchronization. +	 */ +	if (tsk->vfork_done) +		complete_vfork_done(tsk);  }  /* @@ -831,10 +835,6 @@ struct mm_struct *dup_mm(struct task_struct *tsk)  	memcpy(mm, oldmm, sizeof(*mm));  	mm_init_cpumask(mm); -	/* Initializing for Swap token stuff */ -	mm->token_priority = 0; -	mm->last_interval = 0; -  #ifdef CONFIG_TRANSPARENT_HUGEPAGE  	mm->pmd_huge_pte = NULL;  #endif @@ -913,10 +913,6 @@ static int copy_mm(unsigned long clone_flags, struct task_struct *tsk)  		goto fail_nomem;  good_mm: -	/* Initializing for Swap token stuff */ -	mm->token_priority = 0; -	mm->last_interval = 0; -  	tsk->mm = mm;  	tsk->active_mm = mm;  	return 0; @@ -984,9 +980,8 @@ static int copy_io(unsigned long clone_flags, struct task_struct *tsk)  	 * Share io context with parent, if CLONE_IO is set  	 */  	if (clone_flags & CLONE_IO) { -		tsk->io_context = ioc_task_link(ioc); -		if (unlikely(!tsk->io_context)) -			return -ENOMEM; +		ioc_task_link(ioc); +		tsk->io_context = ioc;  	} else if (ioprio_valid(ioc->ioprio)) {  		new_ioc = get_task_io_context(tsk, GFP_KERNEL, NUMA_NO_NODE);  		if (unlikely(!new_ioc)) @@ -1420,6 +1415,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,  	 */  	p->group_leader = p;  	INIT_LIST_HEAD(&p->thread_group); +	INIT_HLIST_HEAD(&p->task_works);  	/* Now that the task is set up, run cgroup callbacks if  	 * necessary. We need to run them before the task is visible  |