diff options
author | Mel Gorman <mgorman@suse.de> | 2013-10-07 06:29:18 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2013-10-09 08:47:41 -0400 |
commit | 2c8a50aa873a7e1d6cc0913362051ff9912dc6ca (patch) | |
tree | ca32297c046a3789b44e1255b94ef8d0b760d1f9 /kernel/sched/fair.c | |
parent | fb13c7ee0ed387bd6bec4b4024a4d49b1bd504f1 (diff) |
sched/numa: Favor placing a task on the preferred node
A tasks preferred node is selected based on the number of faults
recorded for a node but the actual task_numa_migate() conducts a global
search regardless of the preferred nid. This patch checks if the
preferred nid has capacity and if so, searches for a CPU within that
node. This avoids a global search when the preferred node is not
overloaded.
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-41-git-send-email-mgorman@suse.de
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'kernel/sched/fair.c')
-rw-r--r-- | kernel/sched/fair.c | 54 |
1 files changed, 35 insertions, 19 deletions
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 1422765d4b86..09aac90df89e 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c | |||
@@ -1052,6 +1052,20 @@ unlock: | |||
1052 | rcu_read_unlock(); | 1052 | rcu_read_unlock(); |
1053 | } | 1053 | } |
1054 | 1054 | ||
1055 | static void task_numa_find_cpu(struct task_numa_env *env, long imp) | ||
1056 | { | ||
1057 | int cpu; | ||
1058 | |||
1059 | for_each_cpu(cpu, cpumask_of_node(env->dst_nid)) { | ||
1060 | /* Skip this CPU if the source task cannot migrate */ | ||
1061 | if (!cpumask_test_cpu(cpu, tsk_cpus_allowed(env->p))) | ||
1062 | continue; | ||
1063 | |||
1064 | env->dst_cpu = cpu; | ||
1065 | task_numa_compare(env, imp); | ||
1066 | } | ||
1067 | } | ||
1068 | |||
1055 | static int task_numa_migrate(struct task_struct *p) | 1069 | static int task_numa_migrate(struct task_struct *p) |
1056 | { | 1070 | { |
1057 | struct task_numa_env env = { | 1071 | struct task_numa_env env = { |
@@ -1068,7 +1082,8 @@ static int task_numa_migrate(struct task_struct *p) | |||
1068 | }; | 1082 | }; |
1069 | struct sched_domain *sd; | 1083 | struct sched_domain *sd; |
1070 | unsigned long faults; | 1084 | unsigned long faults; |
1071 | int nid, cpu, ret; | 1085 | int nid, ret; |
1086 | long imp; | ||
1072 | 1087 | ||
1073 | /* | 1088 | /* |
1074 | * Pick the lowest SD_NUMA domain, as that would have the smallest | 1089 | * Pick the lowest SD_NUMA domain, as that would have the smallest |
@@ -1085,28 +1100,29 @@ static int task_numa_migrate(struct task_struct *p) | |||
1085 | 1100 | ||
1086 | faults = task_faults(p, env.src_nid); | 1101 | faults = task_faults(p, env.src_nid); |
1087 | update_numa_stats(&env.src_stats, env.src_nid); | 1102 | update_numa_stats(&env.src_stats, env.src_nid); |
1103 | env.dst_nid = p->numa_preferred_nid; | ||
1104 | imp = task_faults(env.p, env.dst_nid) - faults; | ||
1105 | update_numa_stats(&env.dst_stats, env.dst_nid); | ||
1088 | 1106 | ||
1089 | /* Find an alternative node with relatively better statistics */ | 1107 | /* |
1090 | for_each_online_node(nid) { | 1108 | * If the preferred nid has capacity then use it. Otherwise find an |
1091 | long imp; | 1109 | * alternative node with relatively better statistics. |
1092 | 1110 | */ | |
1093 | if (nid == env.src_nid) | 1111 | if (env.dst_stats.has_capacity) { |
1094 | continue; | 1112 | task_numa_find_cpu(&env, imp); |
1095 | 1113 | } else { | |
1096 | /* Only consider nodes that recorded more faults */ | 1114 | for_each_online_node(nid) { |
1097 | imp = task_faults(p, nid) - faults; | 1115 | if (nid == env.src_nid || nid == p->numa_preferred_nid) |
1098 | if (imp < 0) | 1116 | continue; |
1099 | continue; | ||
1100 | 1117 | ||
1101 | env.dst_nid = nid; | 1118 | /* Only consider nodes that recorded more faults */ |
1102 | update_numa_stats(&env.dst_stats, env.dst_nid); | 1119 | imp = task_faults(env.p, nid) - faults; |
1103 | for_each_cpu(cpu, cpumask_of_node(nid)) { | 1120 | if (imp < 0) |
1104 | /* Skip this CPU if the source task cannot migrate */ | ||
1105 | if (!cpumask_test_cpu(cpu, tsk_cpus_allowed(p))) | ||
1106 | continue; | 1121 | continue; |
1107 | 1122 | ||
1108 | env.dst_cpu = cpu; | 1123 | env.dst_nid = nid; |
1109 | task_numa_compare(&env, imp); | 1124 | update_numa_stats(&env.dst_stats, env.dst_nid); |
1125 | task_numa_find_cpu(&env, imp); | ||
1110 | } | 1126 | } |
1111 | } | 1127 | } |
1112 | 1128 | ||