static struct task_struct *dup_task_struct(struct task_struct *orig, int node)
{
 struct task_struct *tsk;
 unsigned long *stack;
 struct vm_struct *stack_vm_area;
 int err;
 if (node == NUMA_NO_NODE)
  node = tsk_fork_get_node(orig);
 tsk = alloc_task_struct_node(node);
 if (!tsk)
  return NULL;
 stack = alloc_thread_stack_node(tsk, node);
 if (!stack)
  goto free_tsk;
 stack_vm_area = task_stack_vm_area(tsk);
 err = arch_dup_task_struct(tsk, orig);
 /*
  * arch_dup_task_struct() clobbers the stack-related fields.  Make
  * sure they're properly initialized before using any stack-related
  * functions again.
  */
 tsk->stack = stack;
#ifdef CONFIG_VMAP_STACK
 tsk->stack_vm_area = stack_vm_area;
#endif
#ifdef CONFIG_THREAD_INFO_IN_TASK
 atomic_set(&tsk->stack_refcount, 1);
#endif
 if (err)
  goto free_stack;
#ifdef CONFIG_SECCOMP
 /*
  * We must handle setting up seccomp filters once we're under
  * the sighand lock in case orig has changed between now and
  * then. Until then, filter must be NULL to avoid messing up
  * the usage counts on the error path calling free_task.
  */
 tsk->seccomp.filter = NULL;
#endif
 setup_thread_stack(tsk, orig);
 clear_user_return_notifier(tsk);
 clear_tsk_need_resched(tsk);
 set_task_stack_end_magic(tsk);
#ifdef CONFIG_CC_STACKPROTECTOR
 tsk->stack_canary = get_random_int();
#endif
 /*
  * One for us, one for whoever does the "release_task()" (usually
  * parent)
  */
 atomic_set(&tsk->usage, 2);
#ifdef CONFIG_BLK_DEV_IO_TRACE
 tsk->btrace_seq = 0;
#endif
 tsk->splice_pipe = NULL;
 tsk->task_frag.page = NULL;
 tsk->wake_q.next = NULL;
 account_kernel_stack(tsk, 1);
 kcov_task_init(tsk);
 return tsk;
free_stack:
 free_thread_stack(tsk);
free_tsk:
 free_task_struct(tsk);
 return NULL;
}

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);
}