mm: sched: numa: Delay PTE scanning until a task is scheduled on a new node
authorMel Gorman <mgorman@suse.de>
Thu, 22 Nov 2012 14:40:03 +0000 (14:40 +0000)
committerMel Gorman <mgorman@suse.de>
Tue, 11 Dec 2012 14:42:56 +0000 (14:42 +0000)
Due to the fact that migrations are driven by the CPU a task is running
on there is no point tracking NUMA faults until one task runs on a new
node. This patch tracks the first node used by an address space. Until
it changes, PTE scanning is disabled and no NUMA hinting faults are
trapped. This should help workloads that are short-lived, do not care
about NUMA placement or have bound themselves to a single node.

This takes advantage of the logic in "mm: sched: numa: Implement slow
start for working set sampling" to delay when the checks are made. This
will take advantage of processes that set their CPU and node bindings
early in their lifetime. It will also potentially allow any initial load
balancing to take place.

Signed-off-by: Mel Gorman <mgorman@suse.de>
include/linux/mm_types.h
kernel/fork.c
kernel/sched/fair.c
kernel/sched/features.h

index e850a23dd6ecd9c76743f579bad5f5f4df0d3cd5..197422a1598c38d21a01695286bd6f9e473357bc 100644 (file)
@@ -418,10 +418,20 @@ struct mm_struct {
 
        /* numa_scan_seq prevents two threads setting pte_numa */
        int numa_scan_seq;
+
+       /*
+        * The first node a task was scheduled on. If a task runs on
+        * a different node than Make PTE Scan Go Now.
+        */
+       int first_nid;
 #endif
        struct uprobes_state uprobes_state;
 };
 
+/* first nid will either be a valid NID or one of these values */
+#define NUMA_PTE_SCAN_INIT     -1
+#define NUMA_PTE_SCAN_ACTIVE   -2
+
 static inline void mm_init_cpumask(struct mm_struct *mm)
 {
 #ifdef CONFIG_CPUMASK_OFFSTACK
index 8b20ab7d3aa2951eff91a4e09e0af23a90992747..296ea308096d4c37bd03ff45d833bd32474d7081 100644 (file)
@@ -820,6 +820,9 @@ struct mm_struct *dup_mm(struct task_struct *tsk)
 
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
        mm->pmd_huge_pte = NULL;
+#endif
+#ifdef CONFIG_NUMA_BALANCING
+       mm->first_nid = NUMA_PTE_SCAN_INIT;
 #endif
        if (!mm_init(mm, tsk))
                goto fail_nomem;
index 7a02a2082e95154d5094ded219b20f76ac98a525..3e18f611a5aa6d15e41c2e32186da7587e386ef7 100644 (file)
@@ -860,6 +860,24 @@ void task_numa_work(struct callback_head *work)
        if (p->flags & PF_EXITING)
                return;
 
+       /*
+        * We do not care about task placement until a task runs on a node
+        * other than the first one used by the address space. This is
+        * largely because migrations are driven by what CPU the task
+        * is running on. If it's never scheduled on another node, it'll
+        * not migrate so why bother trapping the fault.
+        */
+       if (mm->first_nid == NUMA_PTE_SCAN_INIT)
+               mm->first_nid = numa_node_id();
+       if (mm->first_nid != NUMA_PTE_SCAN_ACTIVE) {
+               /* Are we running on a new node yet? */
+               if (numa_node_id() == mm->first_nid &&
+                   !sched_feat_numa(NUMA_FORCE))
+                       return;
+
+               mm->first_nid = NUMA_PTE_SCAN_ACTIVE;
+       }
+
        /*
         * Reset the scan period if enough time has gone by. Objective is that
         * scanning will be reduced if pages are properly placed. As tasks
index d2373a3e32528ae6869248188108dc2283cd249e..e7c25fff1e94df70faab87d4d97772ba2a2cdd4e 100644 (file)
@@ -65,8 +65,10 @@ SCHED_FEAT(LB_MIN, false)
 /*
  * Apply the automatic NUMA scheduling policy. Enabled automatically
  * at runtime if running on a NUMA machine. Can be controlled via
- * numa_balancing=
+ * numa_balancing=. Allow PTE scanning to be forced on UMA machines
+ * for debugging the core machinery.
  */
 #ifdef CONFIG_NUMA_BALANCING
 SCHED_FEAT(NUMA,       false)
+SCHED_FEAT(NUMA_FORCE, false)
 #endif