diff options
Diffstat (limited to 'kernel/fork.c')
| -rw-r--r-- | kernel/fork.c | 69 | 
1 files changed, 32 insertions, 37 deletions
diff --git a/kernel/fork.c b/kernel/fork.c index 541fd805fb88..f9572f416126 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -125,6 +125,15 @@ int nr_threads;			/* The idle threads do not count.. */  static int max_threads;		/* tunable limit on nr_threads */ +#define NAMED_ARRAY_INDEX(x)	[x] = __stringify(x) + +static const char * const resident_page_types[] = { +	NAMED_ARRAY_INDEX(MM_FILEPAGES), +	NAMED_ARRAY_INDEX(MM_ANONPAGES), +	NAMED_ARRAY_INDEX(MM_SWAPENTS), +	NAMED_ARRAY_INDEX(MM_SHMEMPAGES), +}; +  DEFINE_PER_CPU(unsigned long, process_counts) = 0;  __cacheline_aligned DEFINE_RWLOCK(tasklist_lock);  /* outer */ @@ -645,12 +654,15 @@ static void check_mm(struct mm_struct *mm)  {  	int i; +	BUILD_BUG_ON_MSG(ARRAY_SIZE(resident_page_types) != NR_MM_COUNTERS, +			 "Please make sure 'struct resident_page_types[]' is updated as well"); +  	for (i = 0; i < NR_MM_COUNTERS; i++) {  		long x = atomic_long_read(&mm->rss_stat.count[i]);  		if (unlikely(x)) -			printk(KERN_ALERT "BUG: Bad rss-counter state " -					  "mm:%p idx:%d val:%ld\n", mm, i, x); +			pr_alert("BUG: Bad rss-counter state mm:%p type:%s val:%ld\n", +				 mm, resident_page_types[i], x);  	}  	if (mm_pgtables_bytes(mm)) @@ -768,6 +780,7 @@ static void set_max_threads(unsigned int max_threads_suggested)  int arch_task_struct_size __read_mostly;  #endif +#ifndef CONFIG_ARCH_TASK_STRUCT_ALLOCATOR  static void task_struct_whitelist(unsigned long *offset, unsigned long *size)  {  	/* Fetch thread_struct whitelist for the architecture. */ @@ -782,6 +795,7 @@ static void task_struct_whitelist(unsigned long *offset, unsigned long *size)  	else  		*offset += offsetof(struct task_struct, thread);  } +#endif /* CONFIG_ARCH_TASK_STRUCT_ALLOCATOR */  void __init fork_init(void)  { @@ -901,10 +915,12 @@ static struct task_struct *dup_task_struct(struct task_struct *orig, int node)  		tsk->cpus_ptr = &tsk->cpus_mask;  	/* -	 * One for us, one for whoever does the "release_task()" (usually -	 * parent) +	 * One for the user space visible state that goes away when reaped. +	 * One for the scheduler.  	 */ -	refcount_set(&tsk->usage, 2); +	refcount_set(&tsk->rcu_users, 2); +	/* One for the rcu users */ +	refcount_set(&tsk->usage, 1);  #ifdef CONFIG_BLK_DEV_IO_TRACE  	tsk->btrace_seq = 0;  #endif @@ -1007,7 +1023,6 @@ static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p,  	mm_init_owner(mm, p);  	RCU_INIT_POINTER(mm->exe_file, NULL);  	mmu_notifier_mm_init(mm); -	hmm_mm_init(mm);  	init_tlb_flush_pending(mm);  #if defined(CONFIG_TRANSPARENT_HUGEPAGE) && !USE_SPLIT_PMD_PTLOCKS  	mm->pmd_huge_pte = NULL; @@ -1517,28 +1532,17 @@ void __cleanup_sighand(struct sighand_struct *sighand)  	}  } -#ifdef CONFIG_POSIX_TIMERS  /*   * Initialize POSIX timer handling for a thread group.   */  static void posix_cpu_timers_init_group(struct signal_struct *sig)  { +	struct posix_cputimers *pct = &sig->posix_cputimers;  	unsigned long cpu_limit;  	cpu_limit = READ_ONCE(sig->rlim[RLIMIT_CPU].rlim_cur); -	if (cpu_limit != RLIM_INFINITY) { -		sig->cputime_expires.prof_exp = cpu_limit * NSEC_PER_SEC; -		sig->cputimer.running = true; -	} - -	/* The timer lists. */ -	INIT_LIST_HEAD(&sig->cpu_timers[0]); -	INIT_LIST_HEAD(&sig->cpu_timers[1]); -	INIT_LIST_HEAD(&sig->cpu_timers[2]); +	posix_cputimers_group_init(pct, cpu_limit);  } -#else -static inline void posix_cpu_timers_init_group(struct signal_struct *sig) { } -#endif  static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)  { @@ -1640,23 +1644,6 @@ static void rt_mutex_init_task(struct task_struct *p)  #endif  } -#ifdef CONFIG_POSIX_TIMERS -/* - * Initialize POSIX timer handling for a single task. - */ -static void posix_cpu_timers_init(struct task_struct *tsk) -{ -	tsk->cputime_expires.prof_exp = 0; -	tsk->cputime_expires.virt_exp = 0; -	tsk->cputime_expires.sched_exp = 0; -	INIT_LIST_HEAD(&tsk->cpu_timers[0]); -	INIT_LIST_HEAD(&tsk->cpu_timers[1]); -	INIT_LIST_HEAD(&tsk->cpu_timers[2]); -} -#else -static inline void posix_cpu_timers_init(struct task_struct *tsk) { } -#endif -  static inline void init_task_pid_links(struct task_struct *task)  {  	enum pid_type type; @@ -1690,6 +1677,14 @@ static inline void rcu_copy_process(struct task_struct *p)  #endif /* #ifdef CONFIG_TASKS_RCU */  } +struct pid *pidfd_pid(const struct file *file) +{ +	if (file->f_op == &pidfd_fops) +		return file->private_data; + +	return ERR_PTR(-EBADF); +} +  static int pidfd_release(struct inode *inode, struct file *file)  {  	struct pid *pid = file->private_data; @@ -1935,7 +1930,7 @@ static __latent_entropy struct task_struct *copy_process(  	task_io_accounting_init(&p->ioac);  	acct_clear_integrals(p); -	posix_cpu_timers_init(p); +	posix_cputimers_init(&p->posix_cputimers);  	p->io_context = NULL;  	audit_set_context(p, NULL);  |