]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/commitdiff
Merge branch 'linus' into sched/core, to resolve conflicts
authorIngo Molnar <mingo@kernel.org>
Sun, 2 Feb 2014 08:45:39 +0000 (09:45 +0100)
committerIngo Molnar <mingo@kernel.org>
Sun, 2 Feb 2014 08:45:39 +0000 (09:45 +0100)
Conflicts:
kernel/sysctl.c

Signed-off-by: Ingo Molnar <mingo@kernel.org>
1  2 
Documentation/sysctl/kernel.txt
include/linux/sched.h
kernel/sched/core.c
kernel/sched/fair.c
kernel/sysctl.c
mm/mempolicy.c

index 760f6e6a2e40afc81aff6bb521e492cc6b10ad1d,e55124e7c40cd0eef8afb92c34913cd68c42faac..04bf16ad8561449e0f0b61aa8a695f350d89f770
@@@ -33,6 -33,11 +33,11 @@@ show up in /proc/sys/kernel
  - domainname
  - hostname
  - hotplug
+ - hung_task_panic
+ - hung_task_check_count
+ - hung_task_timeout_secs
+ - hung_task_warnings
+ - kexec_load_disabled
  - kptr_restrict
  - kstack_depth_to_print       [ X86 only ]
  - l2cr                        [ PPC only ]
@@@ -287,6 -292,56 +292,56 @@@ Default value is "/sbin/hotplug"
  
  ==============================================================
  
+ hung_task_panic:
+ Controls the kernel's behavior when a hung task is detected.
+ This file shows up if CONFIG_DETECT_HUNG_TASK is enabled.
+ 0: continue operation. This is the default behavior.
+ 1: panic immediately.
+ ==============================================================
+ hung_task_check_count:
+ The upper bound on the number of tasks that are checked.
+ This file shows up if CONFIG_DETECT_HUNG_TASK is enabled.
+ ==============================================================
+ hung_task_timeout_secs:
+ Check interval. When a task in D state did not get scheduled
+ for more than this value report a warning.
+ This file shows up if CONFIG_DETECT_HUNG_TASK is enabled.
+ 0: means infinite timeout - no checking done.
+ ==============================================================
+ hung_task_warning:
+ The maximum number of warnings to report. During a check interval
+ When this value is reached, no more the warnings will be reported.
+ This file shows up if CONFIG_DETECT_HUNG_TASK is enabled.
+ -1: report an infinite number of warnings.
+ ==============================================================
+ kexec_load_disabled:
+ A toggle indicating if the kexec_load syscall has been disabled. This
+ value defaults to 0 (false: kexec_load enabled), but can be set to 1
+ (true: kexec_load disabled). Once true, kexec can no longer be used, and
+ the toggle cannot be set back to false. This allows a kexec image to be
+ loaded before disabling the syscall, allowing a system to set up (and
+ later use) an image without it being altered. Generally used together
+ with the "modules_disabled" sysctl.
+ ==============================================================
  kptr_restrict:
  
  This toggle indicates whether restrictions are placed on
@@@ -331,7 -386,7 +386,7 @@@ A toggle value indicating if modules ar
  in an otherwise modular kernel.  This toggle defaults to off
  (0), but can be set true (1).  Once true, modules can be
  neither loaded nor unloaded, and the toggle cannot be set back
- to false.
+ to false.  Generally used with the "kexec_load_disabled" toggle.
  
  ==============================================================
  
@@@ -386,7 -441,8 +441,7 @@@ feature should be disabled. Otherwise, 
  feature is too high then the rate the kernel samples for NUMA hinting
  faults may be controlled by the numa_balancing_scan_period_min_ms,
  numa_balancing_scan_delay_ms, numa_balancing_scan_period_max_ms,
 -numa_balancing_scan_size_mb, numa_balancing_settle_count sysctls and
 -numa_balancing_migrate_deferred.
 +numa_balancing_scan_size_mb, and numa_balancing_settle_count sysctls.
  
  ==============================================================
  
@@@ -427,6 -483,13 +482,6 @@@ rate for each task
  numa_balancing_scan_size_mb is how many megabytes worth of pages are
  scanned for a given scan.
  
 -numa_balancing_migrate_deferred is how many page migrations get skipped
 -unconditionally, after a page migration is skipped because a page is shared
 -with other tasks. This reduces page migration overhead, and determines
 -how much stronger the "move task near its memory" policy scheduler becomes,
 -versus the "move memory near its task" memory management policy, for workloads
 -with shared memory.
 -
  ==============================================================
  
  osrelease, ostype & version:
diff --combined include/linux/sched.h
index ef92953764f2603b2211f1fa201c39475d36e726,68a0e84463a0eb86b273fe14b49bd9b01feab21f..ed867797fe5a01835048cee49f0c674fe17da2cb
@@@ -229,7 -229,7 +229,7 @@@ extern char ___assert_task_state[1 - 2*
  /* get_task_state() */
  #define TASK_REPORT           (TASK_RUNNING | TASK_INTERRUPTIBLE | \
                                 TASK_UNINTERRUPTIBLE | __TASK_STOPPED | \
-                                __TASK_TRACED)
+                                __TASK_TRACED | EXIT_ZOMBIE | EXIT_DEAD)
  
  #define task_is_traced(task)  ((task->state & __TASK_TRACED) != 0)
  #define task_is_stopped(task) ((task->state & __TASK_STOPPED) != 0)
@@@ -391,22 -391,33 +391,33 @@@ arch_get_unmapped_area_topdown(struct f
  static inline void arch_pick_mmap_layout(struct mm_struct *mm) {}
  #endif
  
- extern void set_dumpable(struct mm_struct *mm, int value);
- extern int get_dumpable(struct mm_struct *mm);
  #define SUID_DUMP_DISABLE     0       /* No setuid dumping */
  #define SUID_DUMP_USER                1       /* Dump as user of process */
  #define SUID_DUMP_ROOT                2       /* Dump as root */
  
  /* mm flags */
- /* dumpable bits */
- #define MMF_DUMPABLE      0  /* core dump is permitted */
- #define MMF_DUMP_SECURELY 1  /* core file is readable only by root */
  
+ /* for SUID_DUMP_* above */
  #define MMF_DUMPABLE_BITS 2
  #define MMF_DUMPABLE_MASK ((1 << MMF_DUMPABLE_BITS) - 1)
  
+ extern void set_dumpable(struct mm_struct *mm, int value);
+ /*
+  * This returns the actual value of the suid_dumpable flag. For things
+  * that are using this for checking for privilege transitions, it must
+  * test against SUID_DUMP_USER rather than treating it as a boolean
+  * value.
+  */
+ static inline int __get_dumpable(unsigned long mm_flags)
+ {
+       return mm_flags & MMF_DUMPABLE_MASK;
+ }
+ static inline int get_dumpable(struct mm_struct *mm)
+ {
+       return __get_dumpable(mm->flags);
+ }
  /* coredump filter bits */
  #define MMF_DUMP_ANON_PRIVATE 2
  #define MMF_DUMP_ANON_SHARED  3
@@@ -549,6 -560,7 +560,7 @@@ struct signal_struct 
        atomic_t                sigcnt;
        atomic_t                live;
        int                     nr_threads;
+       struct list_head        thread_head;
  
        wait_queue_head_t       wait_chldexit;  /* for wait4() */
  
@@@ -1227,7 -1239,6 +1239,6 @@@ struct task_struct 
        /* Used for emulating ABI behavior of previous Linux versions */
        unsigned int personality;
  
-       unsigned did_exec:1;
        unsigned in_execve:1;   /* Tell the LSMs that the process is doing an
                                 * execve */
        unsigned in_iowait:1;
        /* PID/PID hash table linkage. */
        struct pid_link pids[PIDTYPE_MAX];
        struct list_head thread_group;
+       struct list_head thread_node;
  
        struct completion *vfork_done;          /* for vfork() */
        int __user *set_child_tid;              /* CLONE_CHILD_SETTID */
        unsigned int numa_scan_period;
        unsigned int numa_scan_period_max;
        int numa_preferred_nid;
 -      int numa_migrate_deferred;
        unsigned long numa_migrate_retry;
        u64 node_stamp;                 /* migration stamp  */
 +      u64 last_task_numa_placement;
 +      u64 last_sum_exec_runtime;
        struct callback_head numa_work;
  
        struct list_head numa_entry;
         * Scheduling placement decisions are made based on the these counts.
         * The values remain static for the duration of a PTE scan
         */
 -      unsigned long *numa_faults;
 +      unsigned long *numa_faults_memory;
        unsigned long total_numa_faults;
  
        /*
         * numa_faults_buffer records faults per node during the current
 -       * scan window. When the scan completes, the counts in numa_faults
 -       * decay and these values are copied.
 +       * scan window. When the scan completes, the counts in
 +       * numa_faults_memory decay and these values are copied.
         */
 -      unsigned long *numa_faults_buffer;
 +      unsigned long *numa_faults_buffer_memory;
 +
 +      /*
 +       * Track the nodes the process was running on when a NUMA hinting
 +       * fault was incurred.
 +       */
 +      unsigned long *numa_faults_cpu;
 +      unsigned long *numa_faults_buffer_cpu;
  
        /*
         * numa_faults_locality tracks if faults recorded during the last
@@@ -1591,8 -1595,8 +1603,8 @@@ extern void task_numa_fault(int last_no
  extern pid_t task_numa_group_id(struct task_struct *p);
  extern void set_numabalancing_state(bool enabled);
  extern void task_numa_free(struct task_struct *p);
 -
 -extern unsigned int sysctl_numa_balancing_migrate_deferred;
 +extern bool should_numa_migrate_memory(struct task_struct *p, struct page *page,
 +                                      int src_nid, int dst_cpu);
  #else
  static inline void task_numa_fault(int last_node, int node, int pages,
                                   int flags)
@@@ -1608,11 -1612,6 +1620,11 @@@ static inline void set_numabalancing_st
  static inline void task_numa_free(struct task_struct *p)
  {
  }
 +static inline bool should_numa_migrate_memory(struct task_struct *p,
 +                              struct page *page, int src_nid, int dst_cpu)
 +{
 +      return true;
 +}
  #endif
  
  static inline struct pid *task_pid(struct task_struct *task)
@@@ -2295,8 -2294,6 +2307,6 @@@ extern struct mm_struct *get_task_mm(st
  extern struct mm_struct *mm_access(struct task_struct *task, unsigned int mode);
  /* Remove the current tasks stale references to the old mm_struct */
  extern void mm_release(struct task_struct *, struct mm_struct *);
- /* Allocate a new mm structure and copy contents from tsk->mm */
- extern struct mm_struct *dup_mm(struct task_struct *tsk);
  
  extern int copy_thread(unsigned long, unsigned long, unsigned long,
                        struct task_struct *);
@@@ -2354,6 -2351,16 +2364,16 @@@ extern bool current_is_single_threaded(
  #define while_each_thread(g, t) \
        while ((t = next_thread(t)) != g)
  
+ #define __for_each_thread(signal, t)  \
+       list_for_each_entry_rcu(t, &(signal)->thread_head, thread_node)
+ #define for_each_thread(p, t)         \
+       __for_each_thread((p)->signal, t)
+ /* Careful: this is a double loop, 'break' won't work as expected. */
+ #define for_each_process_thread(p, t) \
+       for_each_process(p) for_each_thread(p, t)
  static inline int get_nr_threads(struct task_struct *tsk)
  {
        return tsk->signal->nr_threads;
diff --combined kernel/sched/core.c
index a561c9e8e382cff405d5f153dabe6e12ca5d4eb9,b46131ef6aab0ac48149482a03f8354330adf188..210a12acf2cdd2236bdb2e163e15610538b50828
@@@ -1108,6 -1108,7 +1108,7 @@@ int migrate_swap(struct task_struct *cu
        if (!cpumask_test_cpu(arg.src_cpu, tsk_cpus_allowed(arg.dst_task)))
                goto out;
  
+       trace_sched_swap_numa(cur, arg.src_cpu, p, arg.dst_cpu);
        ret = stop_two_cpus(arg.dst_cpu, arg.src_cpu, migrate_swap_stop, &arg);
  
  out:
@@@ -1744,10 -1745,8 +1745,10 @@@ static void __sched_fork(unsigned long 
        p->numa_scan_seq = p->mm ? p->mm->numa_scan_seq : 0;
        p->numa_scan_period = sysctl_numa_balancing_scan_delay;
        p->numa_work.next = &p->numa_work;
 -      p->numa_faults = NULL;
 -      p->numa_faults_buffer = NULL;
 +      p->numa_faults_memory = NULL;
 +      p->numa_faults_buffer_memory = NULL;
 +      p->last_task_numa_placement = 0;
 +      p->last_sum_exec_runtime = 0;
  
        INIT_LIST_HEAD(&p->numa_entry);
        p->numa_group = NULL;
@@@ -1771,7 -1770,29 +1772,29 @@@ void set_numabalancing_state(bool enabl
        numabalancing_enabled = enabled;
  }
  #endif /* CONFIG_SCHED_DEBUG */
- #endif /* CONFIG_NUMA_BALANCING */
+ #ifdef CONFIG_PROC_SYSCTL
+ int sysctl_numa_balancing(struct ctl_table *table, int write,
+                        void __user *buffer, size_t *lenp, loff_t *ppos)
+ {
+       struct ctl_table t;
+       int err;
+       int state = numabalancing_enabled;
+       if (write && !capable(CAP_SYS_ADMIN))
+               return -EPERM;
+       t = *table;
+       t.data = &state;
+       err = proc_dointvec_minmax(&t, write, buffer, lenp, ppos);
+       if (err < 0)
+               return err;
+       if (write)
+               set_numabalancing_state(state);
+       return err;
+ }
+ #endif
+ #endif
  
  /*
   * fork()/clone()-time setup:
@@@ -2455,7 -2476,7 +2478,7 @@@ u64 scheduler_tick_max_deferment(void
        if (time_before_eq(next, now))
                return 0;
  
-       return jiffies_to_usecs(next - now) * NSEC_PER_USEC;
+       return jiffies_to_nsecs(next - now);
  }
  #endif
  
@@@ -4607,6 -4628,7 +4630,7 @@@ int migrate_task_to(struct task_struct 
  
        /* TODO: This is not properly updating schedstats */
  
+       trace_sched_move_numa(p, curr_cpu, target_cpu);
        return stop_one_cpu(curr_cpu, migration_cpu_stop, &arg);
  }
  
@@@ -7856,15 -7878,14 +7880,14 @@@ static int __cfs_schedulable(struct tas
        return ret;
  }
  
- static int cpu_stats_show(struct cgroup_subsys_state *css, struct cftype *cft,
-               struct cgroup_map_cb *cb)
+ static int cpu_stats_show(struct seq_file *sf, void *v)
  {
-       struct task_group *tg = css_tg(css);
+       struct task_group *tg = css_tg(seq_css(sf));
        struct cfs_bandwidth *cfs_b = &tg->cfs_bandwidth;
  
-       cb->fill(cb, "nr_periods", cfs_b->nr_periods);
-       cb->fill(cb, "nr_throttled", cfs_b->nr_throttled);
-       cb->fill(cb, "throttled_time", cfs_b->throttled_time);
+       seq_printf(sf, "nr_periods %d\n", cfs_b->nr_periods);
+       seq_printf(sf, "nr_throttled %d\n", cfs_b->nr_throttled);
+       seq_printf(sf, "throttled_time %llu\n", cfs_b->throttled_time);
  
        return 0;
  }
@@@ -7918,7 -7939,7 +7941,7 @@@ static struct cftype cpu_files[] = 
        },
        {
                .name = "stat",
-               .read_map = cpu_stats_show,
+               .seq_show = cpu_stats_show,
        },
  #endif
  #ifdef CONFIG_RT_GROUP_SCHED
diff --combined kernel/sched/fair.c
index 1f41b122198e59551dac7d4ecb8d71a0d95b53dd,966cc2bfcb77586d2ce9c55986aae2a3f2dce521..4caa8030824d540397dee7462bcb6c71487af706
@@@ -819,6 -819,14 +819,6 @@@ unsigned int sysctl_numa_balancing_scan
  /* Scan @scan_size MB every @scan_period after an initial @scan_delay in ms */
  unsigned int sysctl_numa_balancing_scan_delay = 1000;
  
 -/*
 - * After skipping a page migration on a shared page, skip N more numa page
 - * migrations unconditionally. This reduces the number of NUMA migrations
 - * in shared memory workloads, and has the effect of pulling tasks towards
 - * where their memory lives, over pulling the memory towards the task.
 - */
 -unsigned int sysctl_numa_balancing_migrate_deferred = 16;
 -
  static unsigned int task_nr_scan_windows(struct task_struct *p)
  {
        unsigned long rss = 0;
@@@ -885,26 -893,10 +885,26 @@@ struct numa_group 
        struct list_head task_list;
  
        struct rcu_head rcu;
 +      nodemask_t active_nodes;
        unsigned long total_faults;
 +      /*
 +       * Faults_cpu is used to decide whether memory should move
 +       * towards the CPU. As a consequence, these stats are weighted
 +       * more by CPU use than by memory faults.
 +       */
 +      unsigned long *faults_cpu;
        unsigned long faults[0];
  };
  
 +/* Shared or private faults. */
 +#define NR_NUMA_HINT_FAULT_TYPES 2
 +
 +/* Memory and CPU locality */
 +#define NR_NUMA_HINT_FAULT_STATS (NR_NUMA_HINT_FAULT_TYPES * 2)
 +
 +/* Averaged statistics, and temporary buffers. */
 +#define NR_NUMA_HINT_FAULT_BUCKETS (NR_NUMA_HINT_FAULT_STATS * 2)
 +
  pid_t task_numa_group_id(struct task_struct *p)
  {
        return p->numa_group ? p->numa_group->gid : 0;
  
  static inline int task_faults_idx(int nid, int priv)
  {
 -      return 2 * nid + priv;
 +      return NR_NUMA_HINT_FAULT_TYPES * nid + priv;
  }
  
  static inline unsigned long task_faults(struct task_struct *p, int nid)
  {
 -      if (!p->numa_faults)
 +      if (!p->numa_faults_memory)
                return 0;
  
 -      return p->numa_faults[task_faults_idx(nid, 0)] +
 -              p->numa_faults[task_faults_idx(nid, 1)];
 +      return p->numa_faults_memory[task_faults_idx(nid, 0)] +
 +              p->numa_faults_memory[task_faults_idx(nid, 1)];
  }
  
  static inline unsigned long group_faults(struct task_struct *p, int nid)
                p->numa_group->faults[task_faults_idx(nid, 1)];
  }
  
 +static inline unsigned long group_faults_cpu(struct numa_group *group, int nid)
 +{
 +      return group->faults_cpu[task_faults_idx(nid, 0)] +
 +              group->faults_cpu[task_faults_idx(nid, 1)];
 +}
 +
  /*
   * These return the fraction of accesses done by a particular task, or
   * task group, on a particular numa node.  The group weight is given a
@@@ -949,7 -935,7 +949,7 @@@ static inline unsigned long task_weight
  {
        unsigned long total_faults;
  
 -      if (!p->numa_faults)
 +      if (!p->numa_faults_memory)
                return 0;
  
        total_faults = p->total_numa_faults;
@@@ -968,69 -954,6 +968,69 @@@ static inline unsigned long group_weigh
        return 1000 * group_faults(p, nid) / p->numa_group->total_faults;
  }
  
 +bool should_numa_migrate_memory(struct task_struct *p, struct page * page,
 +                              int src_nid, int dst_cpu)
 +{
 +      struct numa_group *ng = p->numa_group;
 +      int dst_nid = cpu_to_node(dst_cpu);
 +      int last_cpupid, this_cpupid;
 +
 +      this_cpupid = cpu_pid_to_cpupid(dst_cpu, current->pid);
 +
 +      /*
 +       * Multi-stage node selection is used in conjunction with a periodic
 +       * migration fault to build a temporal task<->page relation. By using
 +       * a two-stage filter we remove short/unlikely relations.
 +       *
 +       * Using P(p) ~ n_p / n_t as per frequentist probability, we can equate
 +       * a task's usage of a particular page (n_p) per total usage of this
 +       * page (n_t) (in a given time-span) to a probability.
 +       *
 +       * Our periodic faults will sample this probability and getting the
 +       * same result twice in a row, given these samples are fully
 +       * independent, is then given by P(n)^2, provided our sample period
 +       * is sufficiently short compared to the usage pattern.
 +       *
 +       * This quadric squishes small probabilities, making it less likely we
 +       * act on an unlikely task<->page relation.
 +       */
 +      last_cpupid = page_cpupid_xchg_last(page, this_cpupid);
 +      if (!cpupid_pid_unset(last_cpupid) &&
 +                              cpupid_to_nid(last_cpupid) != dst_nid)
 +              return false;
 +
 +      /* Always allow migrate on private faults */
 +      if (cpupid_match_pid(p, last_cpupid))
 +              return true;
 +
 +      /* A shared fault, but p->numa_group has not been set up yet. */
 +      if (!ng)
 +              return true;
 +
 +      /*
 +       * Do not migrate if the destination is not a node that
 +       * is actively used by this numa group.
 +       */
 +      if (!node_isset(dst_nid, ng->active_nodes))
 +              return false;
 +
 +      /*
 +       * Source is a node that is not actively used by this
 +       * numa group, while the destination is. Migrate.
 +       */
 +      if (!node_isset(src_nid, ng->active_nodes))
 +              return true;
 +
 +      /*
 +       * Both source and destination are nodes in active
 +       * use by this numa group. Maximize memory bandwidth
 +       * by migrating from more heavily used groups, to less
 +       * heavily used ones, spreading the load around.
 +       * Use a 1/4 hysteresis to avoid spurious page movement.
 +       */
 +      return group_faults(p, dst_nid) < (group_faults(p, src_nid) * 3 / 4);
 +}
 +
  static unsigned long weighted_cpuload(const int cpu);
  static unsigned long source_load(int cpu, int type);
  static unsigned long target_load(int cpu, int type);
@@@ -1327,11 -1250,15 +1327,15 @@@ static int task_numa_migrate(struct tas
        p->numa_scan_period = task_scan_min(p);
  
        if (env.best_task == NULL) {
-               int ret = migrate_task_to(p, env.best_cpu);
+               ret = migrate_task_to(p, env.best_cpu);
+               if (ret != 0)
+                       trace_sched_stick_numa(p, env.src_cpu, env.best_cpu);
                return ret;
        }
  
        ret = migrate_swap(p, env.best_task);
+       if (ret != 0)
+               trace_sched_stick_numa(p, env.src_cpu, task_cpu(env.best_task));
        put_task_struct(env.best_task);
        return ret;
  }
  static void numa_migrate_preferred(struct task_struct *p)
  {
        /* This task has no NUMA fault statistics yet */
 -      if (unlikely(p->numa_preferred_nid == -1 || !p->numa_faults))
 +      if (unlikely(p->numa_preferred_nid == -1 || !p->numa_faults_memory))
                return;
  
        /* Periodically retry migrating the task to the preferred node */
        task_numa_migrate(p);
  }
  
 +/*
 + * Find the nodes on which the workload is actively running. We do this by
 + * tracking the nodes from which NUMA hinting faults are triggered. This can
 + * be different from the set of nodes where the workload's memory is currently
 + * located.
 + *
 + * The bitmask is used to make smarter decisions on when to do NUMA page
 + * migrations, To prevent flip-flopping, and excessive page migrations, nodes
 + * are added when they cause over 6/16 of the maximum number of faults, but
 + * only removed when they drop below 3/16.
 + */
 +static void update_numa_active_node_mask(struct numa_group *numa_group)
 +{
 +      unsigned long faults, max_faults = 0;
 +      int nid;
 +
 +      for_each_online_node(nid) {
 +              faults = group_faults_cpu(numa_group, nid);
 +              if (faults > max_faults)
 +                      max_faults = faults;
 +      }
 +
 +      for_each_online_node(nid) {
 +              faults = group_faults_cpu(numa_group, nid);
 +              if (!node_isset(nid, numa_group->active_nodes)) {
 +                      if (faults > max_faults * 6 / 16)
 +                              node_set(nid, numa_group->active_nodes);
 +              } else if (faults < max_faults * 3 / 16)
 +                      node_clear(nid, numa_group->active_nodes);
 +      }
 +}
 +
  /*
   * When adapting the scan rate, the period is divided into NUMA_PERIOD_SLOTS
   * increments. The more local the fault statistics are, the higher the scan
@@@ -1460,41 -1355,11 +1464,41 @@@ static void update_task_scan_period(str
        memset(p->numa_faults_locality, 0, sizeof(p->numa_faults_locality));
  }
  
 +/*
 + * Get the fraction of time the task has been running since the last
 + * NUMA placement cycle. The scheduler keeps similar statistics, but
 + * decays those on a 32ms period, which is orders of magnitude off
 + * from the dozens-of-seconds NUMA balancing period. Use the scheduler
 + * stats only if the task is so new there are no NUMA statistics yet.
 + */
 +static u64 numa_get_avg_runtime(struct task_struct *p, u64 *period)
 +{
 +      u64 runtime, delta, now;
 +      /* Use the start of this time slice to avoid calculations. */
 +      now = p->se.exec_start;
 +      runtime = p->se.sum_exec_runtime;
 +
 +      if (p->last_task_numa_placement) {
 +              delta = runtime - p->last_sum_exec_runtime;
 +              *period = now - p->last_task_numa_placement;
 +      } else {
 +              delta = p->se.avg.runnable_avg_sum;
 +              *period = p->se.avg.runnable_avg_period;
 +      }
 +
 +      p->last_sum_exec_runtime = runtime;
 +      p->last_task_numa_placement = now;
 +
 +      return delta;
 +}
 +
  static void task_numa_placement(struct task_struct *p)
  {
        int seq, nid, max_nid = -1, max_group_nid = -1;
        unsigned long max_faults = 0, max_group_faults = 0;
        unsigned long fault_types[2] = { 0, 0 };
 +      unsigned long total_faults;
 +      u64 runtime, period;
        spinlock_t *group_lock = NULL;
  
        seq = ACCESS_ONCE(p->mm->numa_scan_seq);
        p->numa_scan_seq = seq;
        p->numa_scan_period_max = task_scan_max(p);
  
 +      total_faults = p->numa_faults_locality[0] +
 +                     p->numa_faults_locality[1];
 +      runtime = numa_get_avg_runtime(p, &period);
 +
        /* If the task is part of a group prevent parallel updates to group stats */
        if (p->numa_group) {
                group_lock = &p->numa_group->lock;
                unsigned long faults = 0, group_faults = 0;
                int priv, i;
  
 -              for (priv = 0; priv < 2; priv++) {
 -                      long diff;
 +              for (priv = 0; priv < NR_NUMA_HINT_FAULT_TYPES; priv++) {
 +                      long diff, f_diff, f_weight;
  
                        i = task_faults_idx(nid, priv);
 -                      diff = -p->numa_faults[i];
  
                        /* Decay existing window, copy faults since last scan */
 -                      p->numa_faults[i] >>= 1;
 -                      p->numa_faults[i] += p->numa_faults_buffer[i];
 -                      fault_types[priv] += p->numa_faults_buffer[i];
 -                      p->numa_faults_buffer[i] = 0;
 +                      diff = p->numa_faults_buffer_memory[i] - p->numa_faults_memory[i] / 2;
 +                      fault_types[priv] += p->numa_faults_buffer_memory[i];
 +                      p->numa_faults_buffer_memory[i] = 0;
  
 -                      faults += p->numa_faults[i];
 -                      diff += p->numa_faults[i];
 +                      /*
 +                       * Normalize the faults_from, so all tasks in a group
 +                       * count according to CPU use, instead of by the raw
 +                       * number of faults. Tasks with little runtime have
 +                       * little over-all impact on throughput, and thus their
 +                       * faults are less important.
 +                       */
 +                      f_weight = div64_u64(runtime << 16, period + 1);
 +                      f_weight = (f_weight * p->numa_faults_buffer_cpu[i]) /
 +                                 (total_faults + 1);
 +                      f_diff = f_weight - p->numa_faults_cpu[i] / 2;
 +                      p->numa_faults_buffer_cpu[i] = 0;
 +
 +                      p->numa_faults_memory[i] += diff;
 +                      p->numa_faults_cpu[i] += f_diff;
 +                      faults += p->numa_faults_memory[i];
                        p->total_numa_faults += diff;
                        if (p->numa_group) {
                                /* safe because we can only change our own group */
                                p->numa_group->faults[i] += diff;
 +                              p->numa_group->faults_cpu[i] += f_diff;
                                p->numa_group->total_faults += diff;
                                group_faults += p->numa_group->faults[i];
                        }
        update_task_scan_period(p, fault_types[0], fault_types[1]);
  
        if (p->numa_group) {
 +              update_numa_active_node_mask(p->numa_group);
                /*
                 * If the preferred task and group nids are different,
                 * iterate over the nodes again to find the best place.
@@@ -1618,7 -1465,7 +1622,7 @@@ static void task_numa_group(struct task
  
        if (unlikely(!p->numa_group)) {
                unsigned int size = sizeof(struct numa_group) +
 -                                  2*nr_node_ids*sizeof(unsigned long);
 +                                  4*nr_node_ids*sizeof(unsigned long);
  
                grp = kzalloc(size, GFP_KERNEL | __GFP_NOWARN);
                if (!grp)
                spin_lock_init(&grp->lock);
                INIT_LIST_HEAD(&grp->task_list);
                grp->gid = p->pid;
 +              /* Second half of the array tracks nids where faults happen */
 +              grp->faults_cpu = grp->faults + NR_NUMA_HINT_FAULT_TYPES *
 +                                              nr_node_ids;
 +
 +              node_set(task_node(current), grp->active_nodes);
  
 -              for (i = 0; i < 2*nr_node_ids; i++)
 -                      grp->faults[i] = p->numa_faults[i];
 +              for (i = 0; i < NR_NUMA_HINT_FAULT_STATS * nr_node_ids; i++)
 +                      grp->faults[i] = p->numa_faults_memory[i];
  
                grp->total_faults = p->total_numa_faults;
  
  
        double_lock(&my_grp->lock, &grp->lock);
  
 -      for (i = 0; i < 2*nr_node_ids; i++) {
 -              my_grp->faults[i] -= p->numa_faults[i];
 -              grp->faults[i] += p->numa_faults[i];
 +      for (i = 0; i < NR_NUMA_HINT_FAULT_STATS * nr_node_ids; i++) {
 +              my_grp->faults[i] -= p->numa_faults_memory[i];
 +              grp->faults[i] += p->numa_faults_memory[i];
        }
        my_grp->total_faults -= p->total_numa_faults;
        grp->total_faults += p->total_numa_faults;
@@@ -1720,12 -1562,12 +1724,12 @@@ void task_numa_free(struct task_struct 
  {
        struct numa_group *grp = p->numa_group;
        int i;
 -      void *numa_faults = p->numa_faults;
 +      void *numa_faults = p->numa_faults_memory;
  
        if (grp) {
                spin_lock(&grp->lock);
 -              for (i = 0; i < 2*nr_node_ids; i++)
 -                      grp->faults[i] -= p->numa_faults[i];
 +              for (i = 0; i < NR_NUMA_HINT_FAULT_STATS * nr_node_ids; i++)
 +                      grp->faults[i] -= p->numa_faults_memory[i];
                grp->total_faults -= p->total_numa_faults;
  
                list_del(&p->numa_entry);
                put_numa_group(grp);
        }
  
 -      p->numa_faults = NULL;
 -      p->numa_faults_buffer = NULL;
 +      p->numa_faults_memory = NULL;
 +      p->numa_faults_buffer_memory = NULL;
 +      p->numa_faults_cpu= NULL;
 +      p->numa_faults_buffer_cpu = NULL;
        kfree(numa_faults);
  }
  
  /*
   * Got a PROT_NONE fault for a page on @node.
   */
 -void task_numa_fault(int last_cpupid, int node, int pages, int flags)
 +void task_numa_fault(int last_cpupid, int mem_node, int pages, int flags)
  {
        struct task_struct *p = current;
        bool migrated = flags & TNF_MIGRATED;
 +      int cpu_node = task_node(current);
        int priv;
  
        if (!numabalancing_enabled)
                return;
  
        /* Allocate buffer to track faults on a per-node basis */
 -      if (unlikely(!p->numa_faults)) {
 -              int size = sizeof(*p->numa_faults) * 2 * nr_node_ids;
 +      if (unlikely(!p->numa_faults_memory)) {
 +              int size = sizeof(*p->numa_faults_memory) *
 +                         NR_NUMA_HINT_FAULT_BUCKETS * nr_node_ids;
  
 -              /* numa_faults and numa_faults_buffer share the allocation */
 -              p->numa_faults = kzalloc(size * 2, GFP_KERNEL|__GFP_NOWARN);
 -              if (!p->numa_faults)
 +              p->numa_faults_memory = kzalloc(size, GFP_KERNEL|__GFP_NOWARN);
 +              if (!p->numa_faults_memory)
                        return;
  
 -              BUG_ON(p->numa_faults_buffer);
 -              p->numa_faults_buffer = p->numa_faults + (2 * nr_node_ids);
 +              BUG_ON(p->numa_faults_buffer_memory);
 +              /*
 +               * The averaged statistics, shared & private, memory & cpu,
 +               * occupy the first half of the array. The second half of the
 +               * array is for current counters, which are averaged into the
 +               * first set by task_numa_placement.
 +               */
 +              p->numa_faults_cpu = p->numa_faults_memory + (2 * nr_node_ids);
 +              p->numa_faults_buffer_memory = p->numa_faults_memory + (4 * nr_node_ids);
 +              p->numa_faults_buffer_cpu = p->numa_faults_memory + (6 * nr_node_ids);
                p->total_numa_faults = 0;
                memset(p->numa_faults_locality, 0, sizeof(p->numa_faults_locality));
        }
        if (migrated)
                p->numa_pages_migrated += pages;
  
 -      p->numa_faults_buffer[task_faults_idx(node, priv)] += pages;
 +      p->numa_faults_buffer_memory[task_faults_idx(mem_node, priv)] += pages;
 +      p->numa_faults_buffer_cpu[task_faults_idx(cpu_node, priv)] += pages;
        p->numa_faults_locality[!!(flags & TNF_FAULT_LOCAL)] += pages;
  }
  
@@@ -4953,7 -4783,7 +4957,7 @@@ static bool migrate_improves_locality(s
  {
        int src_nid, dst_nid;
  
 -      if (!sched_feat(NUMA_FAVOUR_HIGHER) || !p->numa_faults ||
 +      if (!sched_feat(NUMA_FAVOUR_HIGHER) || !p->numa_faults_memory ||
            !(env->sd->flags & SD_NUMA)) {
                return false;
        }
@@@ -4984,7 -4814,7 +4988,7 @@@ static bool migrate_degrades_locality(s
        if (!sched_feat(NUMA) || !sched_feat(NUMA_RESIST_LOWER))
                return false;
  
 -      if (!p->numa_faults || !(env->sd->flags & SD_NUMA))
 +      if (!p->numa_faults_memory || !(env->sd->flags & SD_NUMA))
                return false;
  
        src_nid = cpu_to_node(env->src_cpu);
diff --combined kernel/sysctl.c
index b41d61d95c14bd9365fb5630f59c55447841115e,49e13e1f8fe6a5e481edb3026ae20360918986c3..7754ff16f3342c42d21509437c4c8f3c110694f6
@@@ -62,6 -62,7 +62,7 @@@
  #include <linux/capability.h>
  #include <linux/binfmts.h>
  #include <linux/sched/sysctl.h>
+ #include <linux/kexec.h>
  
  #include <asm/uaccess.h>
  #include <asm/processor.h>
@@@ -95,8 -96,6 +96,6 @@@
  #if defined(CONFIG_SYSCTL)
  
  /* External variables not in a header file. */
- extern int sysctl_overcommit_memory;
- extern int sysctl_overcommit_ratio;
  extern int max_threads;
  extern int suid_dumpable;
  #ifdef CONFIG_COREDUMP
@@@ -122,6 -121,8 +121,8 @@@ extern int blk_iopoll_enabled
  static int sixty = 60;
  #endif
  
+ static int __maybe_unused neg_one = -1;
  static int zero;
  static int __maybe_unused one = 1;
  static int __maybe_unused two = 2;
@@@ -384,6 -385,22 +385,15 @@@ static struct ctl_table kern_table[] = 
                .mode           = 0644,
                .proc_handler   = proc_dointvec,
        },
 -      {
 -              .procname       = "numa_balancing_migrate_deferred",
 -              .data           = &sysctl_numa_balancing_migrate_deferred,
 -              .maxlen         = sizeof(unsigned int),
 -              .mode           = 0644,
 -              .proc_handler   = proc_dointvec,
 -      },
+       {
+               .procname       = "numa_balancing",
+               .data           = NULL, /* filled in by handler */
+               .maxlen         = sizeof(unsigned int),
+               .mode           = 0644,
+               .proc_handler   = sysctl_numa_balancing,
+               .extra1         = &zero,
+               .extra2         = &one,
+       },
  #endif /* CONFIG_NUMA_BALANCING */
  #endif /* CONFIG_SCHED_DEBUG */
        {
                .proc_handler   = proc_dointvec,
        },
  #endif
+ #ifdef CONFIG_KEXEC
+       {
+               .procname       = "kexec_load_disabled",
+               .data           = &kexec_load_disabled,
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               /* only handle a transition from default "0" to "1" */
+               .proc_handler   = proc_dointvec_minmax,
+               .extra1         = &one,
+               .extra2         = &one,
+       },
+ #endif
  #ifdef CONFIG_MODULES
        {
                .procname       = "modprobe",
        {
                .procname       = "hung_task_warnings",
                .data           = &sysctl_hung_task_warnings,
-               .maxlen         = sizeof(unsigned long),
+               .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = proc_doulongvec_minmax,
+               .proc_handler   = proc_dointvec_minmax,
+               .extra1         = &neg_one,
        },
  #endif
  #ifdef CONFIG_COMPAT
@@@ -1114,7 -1144,14 +1137,14 @@@ static struct ctl_table vm_table[] = 
                .data           = &sysctl_overcommit_ratio,
                .maxlen         = sizeof(sysctl_overcommit_ratio),
                .mode           = 0644,
-               .proc_handler   = proc_dointvec,
+               .proc_handler   = overcommit_ratio_handler,
+       },
+       {
+               .procname       = "overcommit_kbytes",
+               .data           = &sysctl_overcommit_kbytes,
+               .maxlen         = sizeof(sysctl_overcommit_kbytes),
+               .mode           = 0644,
+               .proc_handler   = overcommit_kbytes_handler,
        },
        {
                .procname       = "page-cluster", 
diff --combined mm/mempolicy.c
index 784c11ef771972e5fe2b2503bd1e399abddd1ce1,ae3c8f3595d4ff522f0427b05ace2f7e041da8ad..f520b9da9c1f156aaf5ec2713634570299608428
@@@ -613,7 -613,7 +613,7 @@@ static inline int queue_pages_pgd_range
        return 0;
  }
  
- #ifdef CONFIG_ARCH_USES_NUMA_PROT_NONE
+ #ifdef CONFIG_NUMA_BALANCING
  /*
   * This is used to mark a range of virtual addresses to be inaccessible.
   * These are later cleared by a NUMA hinting fault. Depending on these
@@@ -627,7 -627,6 +627,6 @@@ unsigned long change_prot_numa(struct v
                        unsigned long addr, unsigned long end)
  {
        int nr_updated;
-       BUILD_BUG_ON(_PAGE_NUMA != _PAGE_PROTNONE);
  
        nr_updated = change_protection(vma, addr, end, vma->vm_page_prot, 0, 1);
        if (nr_updated)
@@@ -641,7 -640,7 +640,7 @@@ static unsigned long change_prot_numa(s
  {
        return 0;
  }
- #endif /* CONFIG_ARCH_USES_NUMA_PROT_NONE */
+ #endif /* CONFIG_NUMA_BALANCING */
  
  /*
   * Walk through page tables and collect pages to be migrated.
@@@ -1199,10 -1198,8 +1198,8 @@@ static struct page *new_vma_page(struc
        }
  
        if (PageHuge(page)) {
-               if (vma)
-                       return alloc_huge_page_noerr(vma, address, 1);
-               else
-                       return NULL;
+               BUG_ON(!vma);
+               return alloc_huge_page_noerr(vma, address, 1);
        }
        /*
         * if !vma, alloc_page_vma() will use task or system default policy
@@@ -2304,6 -2301,35 +2301,6 @@@ static void sp_free(struct sp_node *n
        kmem_cache_free(sn_cache, n);
  }
  
 -#ifdef CONFIG_NUMA_BALANCING
 -static bool numa_migrate_deferred(struct task_struct *p, int last_cpupid)
 -{
 -      /* Never defer a private fault */
 -      if (cpupid_match_pid(p, last_cpupid))
 -              return false;
 -
 -      if (p->numa_migrate_deferred) {
 -              p->numa_migrate_deferred--;
 -              return true;
 -      }
 -      return false;
 -}
 -
 -static inline void defer_numa_migrate(struct task_struct *p)
 -{
 -      p->numa_migrate_deferred = sysctl_numa_balancing_migrate_deferred;
 -}
 -#else
 -static inline bool numa_migrate_deferred(struct task_struct *p, int last_cpupid)
 -{
 -      return false;
 -}
 -
 -static inline void defer_numa_migrate(struct task_struct *p)
 -{
 -}
 -#endif /* CONFIG_NUMA_BALANCING */
 -
  /**
   * mpol_misplaced - check whether current page node is valid in policy
   *
@@@ -2377,9 -2403,52 +2374,9 @@@ int mpol_misplaced(struct page *page, s
  
        /* Migrate the page towards the node whose CPU is referencing it */
        if (pol->flags & MPOL_F_MORON) {
 -              int last_cpupid;
 -              int this_cpupid;
 -
                polnid = thisnid;
 -              this_cpupid = cpu_pid_to_cpupid(thiscpu, current->pid);
 -
 -              /*
 -               * Multi-stage node selection is used in conjunction
 -               * with a periodic migration fault to build a temporal
 -               * task<->page relation. By using a two-stage filter we
 -               * remove short/unlikely relations.
 -               *
 -               * Using P(p) ~ n_p / n_t as per frequentist
 -               * probability, we can equate a task's usage of a
 -               * particular page (n_p) per total usage of this
 -               * page (n_t) (in a given time-span) to a probability.
 -               *
 -               * Our periodic faults will sample this probability and
 -               * getting the same result twice in a row, given these
 -               * samples are fully independent, is then given by
 -               * P(n)^2, provided our sample period is sufficiently
 -               * short compared to the usage pattern.
 -               *
 -               * This quadric squishes small probabilities, making
 -               * it less likely we act on an unlikely task<->page
 -               * relation.
 -               */
 -              last_cpupid = page_cpupid_xchg_last(page, this_cpupid);
 -              if (!cpupid_pid_unset(last_cpupid) && cpupid_to_nid(last_cpupid) != thisnid) {
  
 -                      /* See sysctl_numa_balancing_migrate_deferred comment */
 -                      if (!cpupid_match_pid(current, last_cpupid))
 -                              defer_numa_migrate(current);
 -
 -                      goto out;
 -              }
 -
 -              /*
 -               * The quadratic filter above reduces extraneous migration
 -               * of shared pages somewhat. This code reduces it even more,
 -               * reducing the overhead of page migrations of shared pages.
 -               * This makes workloads with shared pages rely more on
 -               * "move task near its memory", and less on "move memory
 -               * towards its task", which is exactly what we want.
 -               */
 -              if (numa_migrate_deferred(current, last_cpupid))
 +              if (!should_numa_migrate_memory(current, page, curnid, thiscpu))
                        goto out;
        }
  
@@@ -2585,7 -2654,7 +2582,7 @@@ void mpol_free_shared_policy(struct sha
  }
  
  #ifdef CONFIG_NUMA_BALANCING
- static bool __initdata numabalancing_override;
+ static int __initdata numabalancing_override;
  
  static void __init check_numabalancing_enable(void)
  {
        if (IS_ENABLED(CONFIG_NUMA_BALANCING_DEFAULT_ENABLED))
                numabalancing_default = true;
  
+       /* Parsed by setup_numabalancing. override == 1 enables, -1 disables */
+       if (numabalancing_override)
+               set_numabalancing_state(numabalancing_override == 1);
        if (nr_node_ids > 1 && !numabalancing_override) {
-               printk(KERN_INFO "Enabling automatic NUMA balancing. "
-                       "Configure with numa_balancing= or sysctl");
+               pr_info("%s automatic NUMA balancing. "
+                       "Configure with numa_balancing= or the "
+                       "kernel.numa_balancing sysctl",
+                       numabalancing_default ? "Enabling" : "Disabling");
                set_numabalancing_state(numabalancing_default);
        }
  }
@@@ -2606,18 -2681,17 +2609,17 @@@ static int __init setup_numabalancing(c
        int ret = 0;
        if (!str)
                goto out;
-       numabalancing_override = true;
  
        if (!strcmp(str, "enable")) {
-               set_numabalancing_state(true);
+               numabalancing_override = 1;
                ret = 1;
        } else if (!strcmp(str, "disable")) {
-               set_numabalancing_state(false);
+               numabalancing_override = -1;
                ret = 1;
        }
  out:
        if (!ret)
-               printk(KERN_WARNING "Unable to parse numa_balancing=\n");
+               pr_warn("Unable to parse numa_balancing=\n");
  
        return ret;
  }
@@@ -2856,7 -2930,7 +2858,7 @@@ void mpol_to_str(char *buffer, int maxl
        unsigned short mode = MPOL_DEFAULT;
        unsigned short flags = 0;
  
-       if (pol && pol != &default_policy) {
+       if (pol && pol != &default_policy && !(pol->flags & MPOL_F_MORON)) {
                mode = pol->mode;
                flags = pol->flags;
        }