3383 lines · 83.0 KB · C
RawDownload
// SPDX-License-Identifier: GPL-2.0-only/* *  linux/kernel/fork.c * *  Copyright (C) 1991, 1992  Linus Torvalds */ /* *  'fork.c' contains the help-routines for the 'fork' system call * (see also entry.S and others). * Fork is rather simple, once you get the hang of it, but the memory * management can be a bitch. See 'mm/memory.c': 'copy_page_range()' */ #include <linux/anon_inodes.h>#include <linux/slab.h>#include <linux/sched/autogroup.h>#include <linux/sched/mm.h>#include <linux/sched/user.h>#include <linux/sched/numa_balancing.h>#include <linux/sched/stat.h>#include <linux/sched/task.h>#include <linux/sched/task_stack.h>#include <linux/sched/cputime.h>#include <linux/sched/ext.h>#include <linux/seq_file.h>#include <linux/rtmutex.h>#include <linux/init.h>#include <linux/unistd.h>#include <linux/module.h>#include <linux/vmalloc.h>#include <linux/completion.h>#include <linux/personality.h>#include <linux/mempolicy.h>#include <linux/sem.h>#include <linux/file.h>#include <linux/fdtable.h>#include <linux/iocontext.h>#include <linux/key.h>#include <linux/kmsan.h>#include <linux/binfmts.h>#include <linux/mman.h>#include <linux/mmu_notifier.h>#include <linux/fs.h>#include <linux/mm.h>#include <linux/mm_inline.h>#include <linux/memblock.h>#include <linux/nsproxy.h>#include <linux/ns/ns_common_types.h>#include <linux/capability.h>#include <linux/cpu.h>#include <linux/cgroup.h>#include <linux/security.h>#include <linux/hugetlb.h>#include <linux/seccomp.h>#include <linux/swap.h>#include <linux/syscalls.h>#include <linux/syscall_user_dispatch.h>#include <linux/jiffies.h>#include <linux/futex.h>#include <linux/compat.h>#include <linux/kthread.h>#include <linux/task_io_accounting_ops.h>#include <linux/rcupdate.h>#include <linux/ptrace.h>#include <linux/mount.h>#include <linux/audit.h>#include <linux/memcontrol.h>#include <linux/ftrace.h>#include <linux/proc_fs.h>#include <linux/profile.h>#include <linux/rmap.h>#include <linux/ksm.h>#include <linux/acct.h>#include <linux/userfaultfd_k.h>#include <linux/tsacct_kern.h>#include <linux/cn_proc.h>#include <linux/freezer.h>#include <linux/delayacct.h>#include <linux/taskstats_kern.h>#include <linux/tty.h>#include <linux/fs_struct.h>#include <linux/magic.h>#include <linux/perf_event.h>#include <linux/posix-timers.h>#include <linux/user-return-notifier.h>#include <linux/oom.h>#include <linux/khugepaged.h>#include <linux/signalfd.h>#include <linux/uprobes.h>#include <linux/aio.h>#include <linux/compiler.h>#include <linux/sysctl.h>#include <linux/kcov.h>#include <linux/livepatch.h>#include <linux/thread_info.h>#include <linux/kstack_erase.h>#include <linux/kasan.h>#include <linux/randomize_kstack.h>#include <linux/scs.h>#include <linux/io_uring.h>#include <linux/io_uring_types.h>#include <linux/bpf.h>#include <linux/stackprotector.h>#include <linux/user_events.h>#include <linux/iommu.h>#include <linux/rseq.h>#include <uapi/linux/pidfd.h>#include <linux/pidfs.h>#include <linux/tick.h>#include <linux/unwind_deferred.h>#include <linux/pgalloc.h>#include <linux/uaccess.h> #include <asm/mmu_context.h>#include <asm/cacheflush.h>#include <asm/tlbflush.h> /* For dup_mmap(). */#include "../mm/internal.h" #include <trace/events/sched.h> #define CREATE_TRACE_POINTS#include <trace/events/task.h> #include <kunit/visibility.h> /* * Minimum number of threads to boot the kernel */#define MIN_THREADS 20 /* * Maximum number of threads */#define MAX_THREADS FUTEX_TID_MASK /* * Protected counters by write_lock_irq(&tasklist_lock) */unsigned long total_forks;	/* Handle normal Linux uptimes. */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 */ #ifdef CONFIG_PROVE_RCUint lockdep_tasklist_lock_is_held(void){	return lockdep_is_held(&tasklist_lock);}EXPORT_SYMBOL_GPL(lockdep_tasklist_lock_is_held);#endif /* #ifdef CONFIG_PROVE_RCU */ int nr_processes(void){	int cpu;	int total = 0; 	for_each_possible_cpu(cpu)		total += per_cpu(process_counts, cpu); 	return total;} void __weak arch_release_task_struct(struct task_struct *tsk){} static struct kmem_cache *task_struct_cachep; static inline struct task_struct *alloc_task_struct_node(int node){	return kmem_cache_alloc_node(task_struct_cachep, GFP_KERNEL, node);} static inline void free_task_struct(struct task_struct *tsk){	kmem_cache_free(task_struct_cachep, tsk);} #ifdef CONFIG_VMAP_STACK/* * vmalloc() is a bit slow, and calling vfree() enough times will force a TLB * flush.  Try to minimize the number of calls by caching stacks. */#define NR_CACHED_STACKS 2static DEFINE_PER_CPU(struct vm_struct *, cached_stacks[NR_CACHED_STACKS]);/* * Allocated stacks are cached and later reused by new threads, so memcg * accounting is performed by the code assigning/releasing stacks to tasks. * We need a zeroed memory without __GFP_ACCOUNT. */#define GFP_VMAP_STACK (GFP_KERNEL | __GFP_ZERO | __GFP_SKIP_KASAN) struct vm_stack {	struct rcu_head rcu;	struct vm_struct *stack_vm_area;}; static struct vm_struct *alloc_thread_stack_node_from_cache(struct task_struct *tsk, int node){	struct vm_struct *vm_area;	unsigned int i; 	/*	 * If the node has memory, we are guaranteed the stacks are backed by local pages.	 * Otherwise the pages are arbitrary.	 *	 * Note that depending on cpuset it is possible we will get migrated to a different	 * node immediately after allocating here, so this does *not* guarantee locality for	 * arbitrary callers.	 */	scoped_guard(preempt) {		if (node != NUMA_NO_NODE && numa_node_id() != node)			return NULL; 		for (i = 0; i < NR_CACHED_STACKS; i++) {			vm_area = this_cpu_xchg(cached_stacks[i], NULL);			if (vm_area)				return vm_area;		}	} 	return NULL;} static bool try_release_thread_stack_to_cache(struct vm_struct *vm_area){	unsigned int i;	int nid; 	/*	 * Don't cache stacks if any of the pages don't match the local domain, unless	 * there is no local memory to begin with.	 *	 * Note that lack of local memory does not automatically mean it makes no difference	 * performance-wise which other domain backs the stack. In this case we are merely	 * trying to avoid constantly going to vmalloc.	 */	scoped_guard(preempt) {		nid = numa_node_id();		if (node_state(nid, N_MEMORY)) {			for (i = 0; i < vm_area->nr_pages; i++) {				struct page *page = vm_area->pages[i];				if (page_to_nid(page) != nid)					return false;			}		} 		for (i = 0; i < NR_CACHED_STACKS; i++) {			struct vm_struct *tmp = NULL; 			if (this_cpu_try_cmpxchg(cached_stacks[i], &tmp, vm_area))				return true;		}	}	return false;} static void thread_stack_free_rcu(struct rcu_head *rh){	struct vm_stack *vm_stack = container_of(rh, struct vm_stack, rcu);	struct vm_struct *vm_area = vm_stack->stack_vm_area; 	if (try_release_thread_stack_to_cache(vm_stack->stack_vm_area))		return; 	vfree(vm_area->addr);} static void thread_stack_delayed_free(struct task_struct *tsk){	struct vm_stack *vm_stack = tsk->stack; 	vm_stack->stack_vm_area = tsk->stack_vm_area;	call_rcu(&vm_stack->rcu, thread_stack_free_rcu);} static int free_vm_stack_cache(unsigned int cpu){	struct vm_struct **cached_vm_stack_areas = per_cpu_ptr(cached_stacks, cpu);	int i; 	for (i = 0; i < NR_CACHED_STACKS; i++) {		struct vm_struct *vm_area = cached_vm_stack_areas[i]; 		if (!vm_area)			continue; 		vfree(vm_area->addr);		cached_vm_stack_areas[i] = NULL;	} 	return 0;} static int memcg_charge_kernel_stack(struct vm_struct *vm_area){	int i;	int ret;	int nr_charged = 0; 	BUG_ON(vm_area->nr_pages != THREAD_SIZE / PAGE_SIZE); 	for (i = 0; i < THREAD_SIZE / PAGE_SIZE; i++) {		ret = memcg_kmem_charge_page(vm_area->pages[i], GFP_KERNEL, 0);		if (ret)			goto err;		nr_charged++;	}	return 0;err:	for (i = 0; i < nr_charged; i++)		memcg_kmem_uncharge_page(vm_area->pages[i], 0);	return ret;} static int alloc_thread_stack_node(struct task_struct *tsk, int node){	struct vm_struct *vm_area;	void *stack; 	vm_area = alloc_thread_stack_node_from_cache(tsk, node);	if (vm_area) {		if (memcg_charge_kernel_stack(vm_area)) {			vfree(vm_area->addr);			return -ENOMEM;		} 		/* Reset stack metadata. */		if (!kasan_hw_tags_enabled())			kasan_unpoison_range(vm_area->addr, THREAD_SIZE); 		stack = kasan_reset_tag(vm_area->addr); 		/* Clear stale pointers from reused stack. */		clear_pages(vm_area->addr, vm_area->nr_pages); 		tsk->stack_vm_area = vm_area;		tsk->stack = stack;		return 0;	} 	stack = __vmalloc_node(THREAD_SIZE, THREAD_ALIGN,				     GFP_VMAP_STACK,				     node, __builtin_return_address(0));	if (!stack)		return -ENOMEM; 	vm_area = find_vm_area(stack);	if (memcg_charge_kernel_stack(vm_area)) {		vfree(stack);		return -ENOMEM;	}	/*	 * We can't call find_vm_area() in interrupt context, and	 * free_thread_stack() can be called in interrupt context,	 * so cache the vm_struct.	 */	tsk->stack_vm_area = vm_area;	stack = kasan_reset_tag(stack);	tsk->stack = stack;	return 0;} static void free_thread_stack(struct task_struct *tsk){	if (!try_release_thread_stack_to_cache(tsk->stack_vm_area))		thread_stack_delayed_free(tsk); 	tsk->stack = NULL;	tsk->stack_vm_area = NULL;} #else /* !CONFIG_VMAP_STACK */ /* * Allocate pages if THREAD_SIZE is >= PAGE_SIZE, otherwise use a * kmemcache based allocator. */#if THREAD_SIZE >= PAGE_SIZE static void thread_stack_free_rcu(struct rcu_head *rh){	__free_pages(virt_to_page(rh), THREAD_SIZE_ORDER);} static void thread_stack_delayed_free(struct task_struct *tsk){	struct rcu_head *rh = tsk->stack; 	call_rcu(rh, thread_stack_free_rcu);} static int alloc_thread_stack_node(struct task_struct *tsk, int node){	struct page *page = alloc_pages_node(node, THREADINFO_GFP,					     THREAD_SIZE_ORDER); 	if (likely(page)) {		tsk->stack = kasan_reset_tag(page_address(page));		return 0;	}	return -ENOMEM;} static void free_thread_stack(struct task_struct *tsk){	thread_stack_delayed_free(tsk);	tsk->stack = NULL;} #else /* !(THREAD_SIZE >= PAGE_SIZE) */ static struct kmem_cache *thread_stack_cache; static void thread_stack_free_rcu(struct rcu_head *rh){	kmem_cache_free(thread_stack_cache, rh);} static void thread_stack_delayed_free(struct task_struct *tsk){	struct rcu_head *rh = tsk->stack; 	call_rcu(rh, thread_stack_free_rcu);} static int alloc_thread_stack_node(struct task_struct *tsk, int node){	unsigned long *stack;	stack = kmem_cache_alloc_node(thread_stack_cache, THREADINFO_GFP, node);	stack = kasan_reset_tag(stack);	tsk->stack = stack;	return stack ? 0 : -ENOMEM;} static void free_thread_stack(struct task_struct *tsk){	thread_stack_delayed_free(tsk);	tsk->stack = NULL;} void thread_stack_cache_init(void){	thread_stack_cache = kmem_cache_create_usercopy("thread_stack",					THREAD_SIZE, THREAD_SIZE, 0, 0,					THREAD_SIZE, NULL);	BUG_ON(thread_stack_cache == NULL);} #endif /* THREAD_SIZE >= PAGE_SIZE */#endif /* CONFIG_VMAP_STACK */ /* SLAB cache for signal_struct structures (tsk->signal) */static struct kmem_cache *signal_cachep; /* SLAB cache for sighand_struct structures (tsk->sighand) */struct kmem_cache *sighand_cachep; /* SLAB cache for files_struct structures (tsk->files) */struct kmem_cache *files_cachep; /* SLAB cache for fs_struct structures (tsk->fs) */struct kmem_cache *fs_cachep; /* SLAB cache for mm_struct structures (tsk->mm) */static struct kmem_cache *mm_cachep; static void account_kernel_stack(struct task_struct *tsk, int account){	if (IS_ENABLED(CONFIG_VMAP_STACK)) {		struct vm_struct *vm_area = task_stack_vm_area(tsk);		int i; 		for (i = 0; i < THREAD_SIZE / PAGE_SIZE; i++)			mod_lruvec_page_state(vm_area->pages[i], NR_KERNEL_STACK_KB,					      account * (PAGE_SIZE / 1024));	} else {		void *stack = task_stack_page(tsk); 		/* All stack pages are in the same node. */		mod_lruvec_kmem_state(stack, NR_KERNEL_STACK_KB,				      account * (THREAD_SIZE / 1024));	}}

Lines 1–500 of 3383.