aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorMel Gorman <mgorman@suse.de>2013-10-07 06:29:11 -0400
committerIngo Molnar <mingo@kernel.org>2013-10-09 06:40:40 -0400
commit6b9a7460b6baf6c77fc3d23d927ddfc3f3f05bf3 (patch)
treeb35642ac95837435740ee6f584ca6d169795891d /kernel
parent58d081b5082dd85e02ac9a1fb151d97395340a09 (diff)
sched/numa: Retry migration of tasks to CPU on a preferred node
When a preferred node is selected for a tasks there is an attempt to migrate the task to a CPU there. This may fail in which case the task will only migrate if the active load balancer takes action. This may never happen if the conditions are not right. This patch will check at NUMA hinting fault time if another attempt should be made to migrate the task. It will only make an attempt once every five seconds. Signed-off-by: Mel Gorman <mgorman@suse.de> Reviewed-by: Rik van Riel <riel@redhat.com> Cc: Andrea Arcangeli <aarcange@redhat.com> Cc: Johannes Weiner <hannes@cmpxchg.org> Cc: Srikar Dronamraju <srikar@linux.vnet.ibm.com> Signed-off-by: Peter Zijlstra <peterz@infradead.org> Link: http://lkml.kernel.org/r/1381141781-10992-34-git-send-email-mgorman@suse.de Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/sched/fair.c30
1 files changed, 23 insertions, 7 deletions
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 51a760081193..f84ac3fb581b 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -1011,6 +1011,23 @@ migrate:
1011 return migrate_task_to(p, env.best_cpu); 1011 return migrate_task_to(p, env.best_cpu);
1012} 1012}
1013 1013
1014/* Attempt to migrate a task to a CPU on the preferred node. */
1015static void numa_migrate_preferred(struct task_struct *p)
1016{
1017 /* Success if task is already running on preferred CPU */
1018 p->numa_migrate_retry = 0;
1019 if (cpu_to_node(task_cpu(p)) == p->numa_preferred_nid)
1020 return;
1021
1022 /* This task has no NUMA fault statistics yet */
1023 if (unlikely(p->numa_preferred_nid == -1))
1024 return;
1025
1026 /* Otherwise, try migrate to a CPU on the preferred node */
1027 if (task_numa_migrate(p) != 0)
1028 p->numa_migrate_retry = jiffies + HZ*5;
1029}
1030
1014static void task_numa_placement(struct task_struct *p) 1031static void task_numa_placement(struct task_struct *p)
1015{ 1032{
1016 int seq, nid, max_nid = -1; 1033 int seq, nid, max_nid = -1;
@@ -1045,17 +1062,12 @@ static void task_numa_placement(struct task_struct *p)
1045 } 1062 }
1046 } 1063 }
1047 1064
1048 /* 1065 /* Preferred node as the node with the most faults */
1049 * Record the preferred node as the node with the most faults,
1050 * requeue the task to be running on the idlest CPU on the
1051 * preferred node and reset the scanning rate to recheck
1052 * the working set placement.
1053 */
1054 if (max_faults && max_nid != p->numa_preferred_nid) { 1066 if (max_faults && max_nid != p->numa_preferred_nid) {
1055 /* Update the preferred nid and migrate task if possible */ 1067 /* Update the preferred nid and migrate task if possible */
1056 p->numa_preferred_nid = max_nid; 1068 p->numa_preferred_nid = max_nid;
1057 p->numa_migrate_seq = 1; 1069 p->numa_migrate_seq = 1;
1058 task_numa_migrate(p); 1070 numa_migrate_preferred(p);
1059 } 1071 }
1060} 1072}
1061 1073
@@ -1111,6 +1123,10 @@ void task_numa_fault(int last_nidpid, int node, int pages, bool migrated)
1111 1123
1112 task_numa_placement(p); 1124 task_numa_placement(p);
1113 1125
1126 /* Retry task to preferred node migration if it previously failed */
1127 if (p->numa_migrate_retry && time_after(jiffies, p->numa_migrate_retry))
1128 numa_migrate_preferred(p);
1129
1114 p->numa_faults_buffer[task_faults_idx(node, priv)] += pages; 1130 p->numa_faults_buffer[task_faults_idx(node, priv)] += pages;
1115} 1131}
1116 1132