]> Git Repo - linux.git/commitdiff
Merge tag 'kernel-clone-v5.9' of git://git.kernel.org/pub/scm/linux/kernel/git/braune...
authorLinus Torvalds <[email protected]>
Wed, 14 Oct 2020 21:32:52 +0000 (14:32 -0700)
committerLinus Torvalds <[email protected]>
Wed, 14 Oct 2020 21:32:52 +0000 (14:32 -0700)
Pull kernel_clone() updates from Christian Brauner:
 "During the v5.9 merge window we reworked the process creation
  codepaths across multiple architectures. After this work we were only
  left with the _do_fork() helper based on the struct kernel_clone_args
  calling convention. As was pointed out _do_fork() isn't valid
  kernelese especially for a helper that isn't just static.

  This series removes the _do_fork() helper and introduces the new
  kernel_clone() helper. The process creation cleanup didn't change the
  name to something more reasonable mainly because _do_fork() was used
  in quite a few places. So sending this as a separate series seemed the
  better strategy.

  I originally intended to send this early in the v5.9 development cycle
  after the merge window had closed but given that this was touching
  quite a few places I decided to defer this until the v5.10 merge
  window"

* tag 'kernel-clone-v5.9' of git://git.kernel.org/pub/scm/linux/kernel/git/brauner/linux:
  sched: remove _do_fork()
  tracing: switch to kernel_clone()
  kgdbts: switch to kernel_clone()
  kprobes: switch to kernel_clone()
  x86: switch to kernel_clone()
  sparc: switch to kernel_clone()
  nios2: switch to kernel_clone()
  m68k: switch to kernel_clone()
  ia64: switch to kernel_clone()
  h8300: switch to kernel_clone()
  fork: introduce kernel_clone()

1  2 
arch/ia64/kernel/process.c
kernel/fork.c
samples/kprobes/kprobe_example.c
samples/kprobes/kretprobe_example.c

index e74e10f19fff84c8367780fa423cd716efe94ffc,126f72490ec764a651466e5b4bc2e78f09111ab5..f25f2f7231969439400754abcae8026ef39671ad
  
  #include "entry.h"
  
 -#ifdef CONFIG_PERFMON
 -# include <asm/perfmon.h>
 -#endif
 -
  #include "sigframe.h"
  
  void (*ia64_mark_idle)(int);
@@@ -170,6 -174,15 +170,6 @@@ do_notify_resume_user(sigset_t *unused
                return;
        }
  
 -#ifdef CONFIG_PERFMON
 -      if (current->thread.pfm_needs_checking)
 -              /*
 -               * Note: pfm_handle_work() allow us to call it with interrupts
 -               * disabled, and may enable interrupts within the function.
 -               */
 -              pfm_handle_work();
 -#endif
 -
        /* deal with pending signal delivery */
        if (test_thread_flag(TIF_SIGPENDING)) {
                local_irq_enable();     /* force interrupt enable */
@@@ -251,15 -264,41 +251,15 @@@ void arch_cpu_idle(void
  void
  ia64_save_extra (struct task_struct *task)
  {
 -#ifdef CONFIG_PERFMON
 -      unsigned long info;
 -#endif
 -
        if ((task->thread.flags & IA64_THREAD_DBG_VALID) != 0)
                ia64_save_debug_regs(&task->thread.dbr[0]);
 -
 -#ifdef CONFIG_PERFMON
 -      if ((task->thread.flags & IA64_THREAD_PM_VALID) != 0)
 -              pfm_save_regs(task);
 -
 -      info = __this_cpu_read(pfm_syst_info);
 -      if (info & PFM_CPUINFO_SYST_WIDE)
 -              pfm_syst_wide_update_task(task, info, 0);
 -#endif
  }
  
  void
  ia64_load_extra (struct task_struct *task)
  {
 -#ifdef CONFIG_PERFMON
 -      unsigned long info;
 -#endif
 -
        if ((task->thread.flags & IA64_THREAD_DBG_VALID) != 0)
                ia64_load_debug_regs(&task->thread.dbr[0]);
 -
 -#ifdef CONFIG_PERFMON
 -      if ((task->thread.flags & IA64_THREAD_PM_VALID) != 0)
 -              pfm_load_regs(task);
 -
 -      info = __this_cpu_read(pfm_syst_info);
 -      if (info & PFM_CPUINFO_SYST_WIDE)
 -              pfm_syst_wide_update_task(task, info, 1);
 -#endif
  }
  
  /*
   *
   *    <clone syscall>         <some kernel call frames>
   *    sys_clone                  :
-  *    _do_fork                _do_fork
+  *    kernel_clone            kernel_clone
   *    copy_thread             copy_thread
   *
   * This means that the stack layout is as follows:
@@@ -393,6 -432,11 +393,6 @@@ copy_thread(unsigned long clone_flags, 
         */
        child_ptregs->cr_ipsr = ((child_ptregs->cr_ipsr | IA64_PSR_BITS_TO_SET)
                                 & ~(IA64_PSR_BITS_TO_CLEAR | IA64_PSR_PP | IA64_PSR_UP));
 -
 -#ifdef CONFIG_PERFMON
 -      if (current->thread.pfm_context)
 -              pfm_inherit(p, child_ptregs);
 -#endif
        return retval;
  }
  
@@@ -411,7 -455,7 +411,7 @@@ asmlinkage long ia64_clone(unsigned lon
                .tls            = tls,
        };
  
-       return _do_fork(&args);
+       return kernel_clone(&args);
  }
  
  static void
@@@ -519,6 -563,15 +519,6 @@@ exit_thread (struct task_struct *tsk
  {
  
        ia64_drop_fpu(tsk);
 -#ifdef CONFIG_PERFMON
 -       /* if needed, stop monitoring and flush state to perfmon context */
 -      if (tsk->thread.pfm_context)
 -              pfm_exit_thread(tsk);
 -
 -      /* free debug register resources */
 -      if (tsk->thread.flags & IA64_THREAD_DBG_VALID)
 -              pfm_release_debug_registers(tsk);
 -#endif
  }
  
  unsigned long
diff --combined kernel/fork.c
index 50c90d3681179125aa89665d9375a5c2dfc20ac2,d822c7a4b9c4354effc99fd2af758da7b3e24984..3ca8f1f83fb3a3b97b764b354ac4299c5ef57a90
@@@ -95,7 -95,6 +95,7 @@@
  #include <linux/stackleak.h>
  #include <linux/kasan.h>
  #include <linux/scs.h>
 +#include <linux/io_uring.h>
  
  #include <asm/pgalloc.h>
  #include <linux/uaccess.h>
@@@ -559,7 -558,7 +559,7 @@@ static __latent_entropy int dup_mmap(st
                                atomic_dec(&inode->i_writecount);
                        i_mmap_lock_write(mapping);
                        if (tmp->vm_flags & VM_SHARED)
 -                              atomic_inc(&mapping->i_mmap_writable);
 +                              mapping_allow_writable(mapping);
                        flush_dcache_mmap_lock(mapping);
                        /* insert tmp into the share list, just after mpnt */
                        vma_interval_tree_insert_after(tmp, mpnt,
  
                mm->map_count++;
                if (!(tmp->vm_flags & VM_WIPEONFORK))
 -                      retval = copy_page_range(mm, oldmm, mpnt);
 +                      retval = copy_page_range(tmp, mpnt);
  
                if (tmp->vm_ops && tmp->vm_ops->open)
                        tmp->vm_ops->open(tmp);
@@@ -729,7 -728,6 +729,7 @@@ void __put_task_struct(struct task_stru
        WARN_ON(refcount_read(&tsk->usage));
        WARN_ON(tsk == current);
  
 +      io_uring_free(tsk);
        cgroup_free(tsk);
        task_numa_free(tsk, true);
        security_task_free(tsk);
@@@ -1013,7 -1011,6 +1013,7 @@@ static struct mm_struct *mm_init(struc
        mm_pgtables_bytes_init(mm);
        mm->map_count = 0;
        mm->locked_vm = 0;
 +      atomic_set(&mm->has_pinned, 0);
        atomic64_set(&mm->pinned_vm, 0);
        memset(&mm->rss_stat, 0, sizeof(mm->rss_stat));
        spin_lock_init(&mm->page_table_lock);
@@@ -1812,25 -1809,6 +1812,25 @@@ static __always_inline void delayed_fre
                free_task(tsk);
  }
  
 +static void copy_oom_score_adj(u64 clone_flags, struct task_struct *tsk)
 +{
 +      /* Skip if kernel thread */
 +      if (!tsk->mm)
 +              return;
 +
 +      /* Skip if spawning a thread or using vfork */
 +      if ((clone_flags & (CLONE_VM | CLONE_THREAD | CLONE_VFORK)) != CLONE_VM)
 +              return;
 +
 +      /* We need to synchronize with __set_oom_adj */
 +      mutex_lock(&oom_adj_mutex);
 +      set_bit(MMF_MULTIPROCESS, &tsk->mm->flags);
 +      /* Update the values in case they were changed after copy_signal */
 +      tsk->signal->oom_score_adj = current->signal->oom_score_adj;
 +      tsk->signal->oom_score_adj_min = current->signal->oom_score_adj_min;
 +      mutex_unlock(&oom_adj_mutex);
 +}
 +
  /*
   * This creates a new process as a copy of the old one,
   * but does not actually start it yet.
@@@ -2004,10 -1982,6 +2004,10 @@@ static __latent_entropy struct task_str
        p->vtime.state = VTIME_INACTIVE;
  #endif
  
 +#ifdef CONFIG_IO_URING
 +      p->io_uring = NULL;
 +#endif
 +
  #if defined(SPLIT_RSS_COUNTING)
        memset(&p->rss_stat, 0, sizeof(p->rss_stat));
  #endif
        trace_task_newtask(p, clone_flags);
        uprobe_copy_process(p, clone_flags);
  
 +      copy_oom_score_adj(clone_flags, p);
 +
        return p;
  
  bad_fork_cancel_cgroup:
@@@ -2412,14 -2384,14 +2412,14 @@@ struct mm_struct *copy_init_mm(void
   *
   * args->exit_signal is expected to be checked for sanity by the caller.
   */
long _do_fork(struct kernel_clone_args *args)
pid_t kernel_clone(struct kernel_clone_args *args)
  {
        u64 clone_flags = args->flags;
        struct completion vfork;
        struct pid *pid;
        struct task_struct *p;
        int trace = 0;
-       long nr;
+       pid_t nr;
  
        /*
         * For legacy clone() calls, CLONE_PIDFD uses the parent_tid argument
@@@ -2505,7 -2477,7 +2505,7 @@@ pid_t kernel_thread(int (*fn)(void *), 
                .stack_size     = (unsigned long)arg,
        };
  
-       return _do_fork(&args);
+       return kernel_clone(&args);
  }
  
  #ifdef __ARCH_WANT_SYS_FORK
@@@ -2516,7 -2488,7 +2516,7 @@@ SYSCALL_DEFINE0(fork
                .exit_signal = SIGCHLD,
        };
  
-       return _do_fork(&args);
+       return kernel_clone(&args);
  #else
        /* can not support in nommu mode */
        return -EINVAL;
@@@ -2532,7 -2504,7 +2532,7 @@@ SYSCALL_DEFINE0(vfork
                .exit_signal    = SIGCHLD,
        };
  
-       return _do_fork(&args);
+       return kernel_clone(&args);
  }
  #endif
  
@@@ -2570,7 -2542,7 +2570,7 @@@ SYSCALL_DEFINE5(clone, unsigned long, c
                .tls            = tls,
        };
  
-       return _do_fork(&args);
+       return kernel_clone(&args);
  }
  #endif
  
@@@ -2728,7 -2700,7 +2728,7 @@@ SYSCALL_DEFINE2(clone3, struct clone_ar
        if (!clone3_args_valid(&kargs))
                return -EINVAL;
  
-       return _do_fork(&kargs);
+       return kernel_clone(&kargs);
  }
  #endif
  
@@@ -2891,7 -2863,7 +2891,7 @@@ int unshare_fd(unsigned long unshare_fl
  /*
   * unshare allows a process to 'unshare' part of the process
   * context which was originally shared using clone.  copy_*
-  * functions used by _do_fork() cannot be used here directly
+  * functions used by kernel_clone() cannot be used here directly
   * because they modify an inactive task_struct that is being
   * constructed. Here we are modifying the current, active,
   * task_struct.
@@@ -3042,7 -3014,7 +3042,7 @@@ int unshare_files(struct files_struct *
  }
  
  int sysctl_max_threads(struct ctl_table *table, int write,
 -                     void __user *buffer, size_t *lenp, loff_t *ppos)
 +                     void *buffer, size_t *lenp, loff_t *ppos)
  {
        struct ctl_table t;
        int ret;
index 8b718943d603b64e19ebdb6f69cfef010c113a9d,a02f53836ee1b064976e25cd55ccc4b7a76f0455..365905cb24b1548e9fe488a5a211b760ece55337
@@@ -2,13 -2,13 +2,13 @@@
  /*
   * NOTE: This example is works on x86 and powerpc.
   * Here's a sample kernel module showing the use of kprobes to dump a
-  * stack trace and selected registers when _do_fork() is called.
+  * stack trace and selected registers when kernel_clone() is called.
   *
   * For more information on theory of operation of kprobes, see
 - * Documentation/staging/kprobes.rst
 + * Documentation/trace/kprobes.rst
   *
   * You will see the trace data in /var/log/messages and on the console
-  * whenever _do_fork() is invoked to create a new process.
+  * whenever kernel_clone() is invoked to create a new process.
   */
  
  #include <linux/kernel.h>
@@@ -16,7 -16,7 +16,7 @@@
  #include <linux/kprobes.h>
  
  #define MAX_SYMBOL_LEN        64
- static char symbol[MAX_SYMBOL_LEN] = "_do_fork";
+ static char symbol[MAX_SYMBOL_LEN] = "kernel_clone";
  module_param_string(symbol, symbol, sizeof(symbol), 0644);
  
  /* For each probe you need to allocate a kprobe structure */
index 69fd1235108ac05bde5c7c759f90ba8488da489e,0c40f72369898c5e82836519abed78b64f156393..5dc1bf3baa98b3a1598c8b957af0fef27b74017f
@@@ -8,10 -8,10 +8,10 @@@
   *
   * usage: insmod kretprobe_example.ko func=<func_name>
   *
-  * If no func_name is specified, _do_fork is instrumented
+  * If no func_name is specified, kernel_clone is instrumented
   *
   * For more information on theory of operation of kretprobes, see
 - * Documentation/staging/kprobes.rst
 + * Documentation/trace/kprobes.rst
   *
   * Build and insert the kernel module as done in the kprobe example.
   * You will see the trace data in /var/log/messages and on the console
@@@ -26,7 -26,7 +26,7 @@@
  #include <linux/limits.h>
  #include <linux/sched.h>
  
- static char func_name[NAME_MAX] = "_do_fork";
+ static char func_name[NAME_MAX] = "kernel_clone";
  module_param_string(func, func_name, NAME_MAX, S_IRUGO);
  MODULE_PARM_DESC(func, "Function to kretprobe; this module will report the"
                        " function's execution time");
This page took 0.110301 seconds and 4 git commands to generate.