aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sched
diff options
context:
space:
mode:
authorRik van Riel <riel@redhat.com>2013-10-07 06:29:31 -0400
committerIngo Molnar <mingo@kernel.org>2013-10-09 08:48:06 -0400
commit887c290e82e8950d854730c084904c115fc367ac (patch)
tree9d7064eeb89e08c72b33ae973399ddac59468876 /kernel/sched
parentb32e86b4301e345611f0446265f782a229faadf6 (diff)
sched/numa: Decide whether to favour task or group weights based on swap candidate relationships
This patch separately considers task and group affinities when searching for swap candidates during task NUMA placement. If tasks are not part of a group or the same group then the task weights are considered. Otherwise the group weights are compared. Signed-off-by: Rik van Riel <riel@redhat.com> Cc: Andrea Arcangeli <aarcange@redhat.com> Cc: Johannes Weiner <hannes@cmpxchg.org> Cc: Mel Gorman <mgorman@suse.de> Cc: Srikar Dronamraju <srikar@linux.vnet.ibm.com> Signed-off-by: Peter Zijlstra <peterz@infradead.org> Link: http://lkml.kernel.org/r/1381141781-10992-54-git-send-email-mgorman@suse.de Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'kernel/sched')
-rw-r--r--kernel/sched/fair.c59
1 files changed, 36 insertions, 23 deletions
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 2876a37cdfc4..6f454616fa86 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -1039,13 +1039,15 @@ static void task_numa_assign(struct task_numa_env *env,
1039 * into account that it might be best if task running on the dst_cpu should 1039 * into account that it might be best if task running on the dst_cpu should
1040 * be exchanged with the source task 1040 * be exchanged with the source task
1041 */ 1041 */
1042static void task_numa_compare(struct task_numa_env *env, long imp) 1042static void task_numa_compare(struct task_numa_env *env,
1043 long taskimp, long groupimp)
1043{ 1044{
1044 struct rq *src_rq = cpu_rq(env->src_cpu); 1045 struct rq *src_rq = cpu_rq(env->src_cpu);
1045 struct rq *dst_rq = cpu_rq(env->dst_cpu); 1046 struct rq *dst_rq = cpu_rq(env->dst_cpu);
1046 struct task_struct *cur; 1047 struct task_struct *cur;
1047 long dst_load, src_load; 1048 long dst_load, src_load;
1048 long load; 1049 long load;
1050 long imp = (groupimp > 0) ? groupimp : taskimp;
1049 1051
1050 rcu_read_lock(); 1052 rcu_read_lock();
1051 cur = ACCESS_ONCE(dst_rq->curr); 1053 cur = ACCESS_ONCE(dst_rq->curr);
@@ -1064,10 +1066,19 @@ static void task_numa_compare(struct task_numa_env *env, long imp)
1064 if (!cpumask_test_cpu(env->src_cpu, tsk_cpus_allowed(cur))) 1066 if (!cpumask_test_cpu(env->src_cpu, tsk_cpus_allowed(cur)))
1065 goto unlock; 1067 goto unlock;
1066 1068
1067 imp += task_weight(cur, env->src_nid) + 1069 /*
1068 group_weight(cur, env->src_nid) - 1070 * If dst and source tasks are in the same NUMA group, or not
1069 task_weight(cur, env->dst_nid) - 1071 * in any group then look only at task weights otherwise give
1070 group_weight(cur, env->dst_nid); 1072 * priority to the group weights.
1073 */
1074 if (!cur->numa_group || !env->p->numa_group ||
1075 cur->numa_group == env->p->numa_group) {
1076 imp = taskimp + task_weight(cur, env->src_nid) -
1077 task_weight(cur, env->dst_nid);
1078 } else {
1079 imp = groupimp + group_weight(cur, env->src_nid) -
1080 group_weight(cur, env->dst_nid);
1081 }
1071 } 1082 }
1072 1083
1073 if (imp < env->best_imp) 1084 if (imp < env->best_imp)
@@ -1117,7 +1128,8 @@ unlock:
1117 rcu_read_unlock(); 1128 rcu_read_unlock();
1118} 1129}
1119 1130
1120static void task_numa_find_cpu(struct task_numa_env *env, long imp) 1131static void task_numa_find_cpu(struct task_numa_env *env,
1132 long taskimp, long groupimp)
1121{ 1133{
1122 int cpu; 1134 int cpu;
1123 1135
@@ -1127,7 +1139,7 @@ static void task_numa_find_cpu(struct task_numa_env *env, long imp)
1127 continue; 1139 continue;
1128 1140
1129 env->dst_cpu = cpu; 1141 env->dst_cpu = cpu;
1130 task_numa_compare(env, imp); 1142 task_numa_compare(env, taskimp, groupimp);
1131 } 1143 }
1132} 1144}
1133 1145
@@ -1146,9 +1158,9 @@ static int task_numa_migrate(struct task_struct *p)
1146 .best_cpu = -1 1158 .best_cpu = -1
1147 }; 1159 };
1148 struct sched_domain *sd; 1160 struct sched_domain *sd;
1149 unsigned long weight; 1161 unsigned long taskweight, groupweight;
1150 int nid, ret; 1162 int nid, ret;
1151 long imp; 1163 long taskimp, groupimp;
1152 1164
1153 /* 1165 /*
1154 * Pick the lowest SD_NUMA domain, as that would have the smallest 1166 * Pick the lowest SD_NUMA domain, as that would have the smallest
@@ -1163,15 +1175,17 @@ static int task_numa_migrate(struct task_struct *p)
1163 env.imbalance_pct = 100 + (sd->imbalance_pct - 100) / 2; 1175 env.imbalance_pct = 100 + (sd->imbalance_pct - 100) / 2;
1164 rcu_read_unlock(); 1176 rcu_read_unlock();
1165 1177
1166 weight = task_weight(p, env.src_nid) + group_weight(p, env.src_nid); 1178 taskweight = task_weight(p, env.src_nid);
1179 groupweight = group_weight(p, env.src_nid);
1167 update_numa_stats(&env.src_stats, env.src_nid); 1180 update_numa_stats(&env.src_stats, env.src_nid);
1168 env.dst_nid = p->numa_preferred_nid; 1181 env.dst_nid = p->numa_preferred_nid;
1169 imp = task_weight(p, env.dst_nid) + group_weight(p, env.dst_nid) - weight; 1182 taskimp = task_weight(p, env.dst_nid) - taskweight;
1183 groupimp = group_weight(p, env.dst_nid) - groupweight;
1170 update_numa_stats(&env.dst_stats, env.dst_nid); 1184 update_numa_stats(&env.dst_stats, env.dst_nid);
1171 1185
1172 /* If the preferred nid has capacity, try to use it. */ 1186 /* If the preferred nid has capacity, try to use it. */
1173 if (env.dst_stats.has_capacity) 1187 if (env.dst_stats.has_capacity)
1174 task_numa_find_cpu(&env, imp); 1188 task_numa_find_cpu(&env, taskimp, groupimp);
1175 1189
1176 /* No space available on the preferred nid. Look elsewhere. */ 1190 /* No space available on the preferred nid. Look elsewhere. */
1177 if (env.best_cpu == -1) { 1191 if (env.best_cpu == -1) {
@@ -1180,13 +1194,14 @@ static int task_numa_migrate(struct task_struct *p)
1180 continue; 1194 continue;
1181 1195
1182 /* Only consider nodes where both task and groups benefit */ 1196 /* Only consider nodes where both task and groups benefit */
1183 imp = task_weight(p, nid) + group_weight(p, nid) - weight; 1197 taskimp = task_weight(p, nid) - taskweight;
1184 if (imp < 0) 1198 groupimp = group_weight(p, nid) - groupweight;
1199 if (taskimp < 0 && groupimp < 0)
1185 continue; 1200 continue;
1186 1201
1187 env.dst_nid = nid; 1202 env.dst_nid = nid;
1188 update_numa_stats(&env.dst_stats, env.dst_nid); 1203 update_numa_stats(&env.dst_stats, env.dst_nid);
1189 task_numa_find_cpu(&env, imp); 1204 task_numa_find_cpu(&env, taskimp, groupimp);
1190 } 1205 }
1191 } 1206 }
1192 1207
@@ -4679,10 +4694,9 @@ static bool migrate_improves_locality(struct task_struct *p, struct lb_env *env)
4679 if (dst_nid == p->numa_preferred_nid) 4694 if (dst_nid == p->numa_preferred_nid)
4680 return true; 4695 return true;
4681 4696
4682 /* After the task has settled, check if the new node is better. */ 4697 /* If both task and group weight improve, this move is a winner. */
4683 if (p->numa_migrate_seq >= sysctl_numa_balancing_settle_count && 4698 if (task_weight(p, dst_nid) > task_weight(p, src_nid) &&
4684 task_weight(p, dst_nid) + group_weight(p, dst_nid) > 4699 group_weight(p, dst_nid) > group_weight(p, src_nid))
4685 task_weight(p, src_nid) + group_weight(p, src_nid))
4686 return true; 4700 return true;
4687 4701
4688 return false; 4702 return false;
@@ -4709,10 +4723,9 @@ static bool migrate_degrades_locality(struct task_struct *p, struct lb_env *env)
4709 if (src_nid == p->numa_preferred_nid) 4723 if (src_nid == p->numa_preferred_nid)
4710 return true; 4724 return true;
4711 4725
4712 /* After the task has settled, check if the new node is worse. */ 4726 /* If either task or group weight get worse, don't do it. */
4713 if (p->numa_migrate_seq >= sysctl_numa_balancing_settle_count && 4727 if (task_weight(p, dst_nid) < task_weight(p, src_nid) ||
4714 task_weight(p, dst_nid) + group_weight(p, dst_nid) < 4728 group_weight(p, dst_nid) < group_weight(p, src_nid))
4715 task_weight(p, src_nid) + group_weight(p, src_nid))
4716 return true; 4729 return true;
4717 4730
4718 return false; 4731 return false;