diff options
Diffstat (limited to 'kernel/fork.c')
| -rw-r--r-- | kernel/fork.c | 49 | 
1 files changed, 11 insertions, 38 deletions
| diff --git a/kernel/fork.c b/kernel/fork.c index 3244cc56b697..d75a528f7b21 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -42,6 +42,7 @@  #include <linux/mmu_notifier.h>  #include <linux/fs.h>  #include <linux/mm.h> +#include <linux/mm_inline.h>  #include <linux/vmacache.h>  #include <linux/nsproxy.h>  #include <linux/capability.h> @@ -365,12 +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);  	}  	return new;  }  void vm_area_free(struct vm_area_struct *vma)  { +	free_vma_anon_name(vma);  	kmem_cache_free(vm_area_cachep, vma);  } @@ -754,9 +757,7 @@ void __put_task_struct(struct task_struct *tsk)  	delayacct_tsk_free(tsk);  	put_signal_struct(tsk->signal);  	sched_core_free(tsk); - -	if (!profile_handoff_task(tsk)) -		free_task(tsk); +	free_task(tsk);  }  EXPORT_SYMBOL_GPL(__put_task_struct); @@ -950,7 +951,7 @@ static struct task_struct *dup_task_struct(struct task_struct *orig, int node)  	tsk->splice_pipe = NULL;  	tsk->task_frag.page = NULL;  	tsk->wake_q.next = NULL; -	tsk->pf_io_worker = NULL; +	tsk->worker_private = NULL;  	account_kernel_stack(tsk, 1); @@ -1556,32 +1557,6 @@ out:  	return error;  } -static int copy_io(unsigned long clone_flags, struct task_struct *tsk) -{ -#ifdef CONFIG_BLOCK -	struct io_context *ioc = current->io_context; -	struct io_context *new_ioc; - -	if (!ioc) -		return 0; -	/* -	 * Share io context with parent, if CLONE_IO is set -	 */ -	if (clone_flags & CLONE_IO) { -		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)) -			return -ENOMEM; - -		new_ioc->ioprio = ioc->ioprio; -		put_io_context(new_ioc); -	} -#endif -	return 0; -} -  static int copy_sighand(unsigned long clone_flags, struct task_struct *tsk)  {  	struct sighand_struct *sig; @@ -2032,12 +2007,6 @@ static __latent_entropy struct task_struct *copy_process(  		siginitsetinv(&p->blocked, sigmask(SIGKILL)|sigmask(SIGSTOP));  	} -	/* -	 * This _must_ happen before we call free_task(), i.e. before we jump -	 * to any of the bad_fork_* labels. This is to avoid freeing -	 * p->set_child_tid which is (ab)used as a kthread's data pointer for -	 * kernel threads (PF_KTHREAD). -	 */  	p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? args->child_tid : NULL;  	/*  	 * Clear TID on mm_release()? @@ -2118,12 +2087,16 @@ static __latent_entropy struct task_struct *copy_process(  	p->io_context = NULL;  	audit_set_context(p, NULL);  	cgroup_fork(p); +	if (p->flags & PF_KTHREAD) { +		if (!set_kthread_struct(p)) +			goto bad_fork_cleanup_delayacct; +	}  #ifdef CONFIG_NUMA  	p->mempolicy = mpol_dup(p->mempolicy);  	if (IS_ERR(p->mempolicy)) {  		retval = PTR_ERR(p->mempolicy);  		p->mempolicy = NULL; -		goto bad_fork_cleanup_threadgroup_lock; +		goto bad_fork_cleanup_delayacct;  	}  #endif  #ifdef CONFIG_CPUSETS @@ -2460,8 +2433,8 @@ bad_fork_cleanup_policy:  	lockdep_free_task(p);  #ifdef CONFIG_NUMA  	mpol_put(p->mempolicy); -bad_fork_cleanup_threadgroup_lock:  #endif +bad_fork_cleanup_delayacct:  	delayacct_tsk_free(p);  bad_fork_cleanup_count:  	dec_rlimit_ucounts(task_ucounts(p), UCOUNT_RLIMIT_NPROC, 1); |