aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRik van Riel <riel@redhat.com>2013-10-07 06:29:32 -0400
committerIngo Molnar <mingo@kernel.org>2013-10-09 08:48:08 -0400
commitca28aa53dd95868c9e38917b9881c09dacfacf1a (patch)
tree82d068c0c711dcba8a66d3760d6679586ae07638
parent887c290e82e8950d854730c084904c115fc367ac (diff)
sched/numa: Fix task or group comparison
This patch separately considers task and group affinities when searching for swap candidates during NUMA placement. If tasks are part of the same group, or no group at all, the task weights are considered. Some hysteresis is added to prevent tasks within one group from getting bounced between NUMA nodes due to tiny differences. If tasks are part of different groups, the code compares group weights, in order to favor grouping task groups together. The patch also changes the group weight multiplier to be the same as the task weight multiplier, since the two are no longer added up like before. Signed-off-by: Rik van Riel <riel@redhat.com> Signed-off-by: Mel Gorman <mgorman@suse.de> 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-55-git-send-email-mgorman@suse.de Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--kernel/sched/fair.c32
1 files changed, 25 insertions, 7 deletions
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 6f454616fa86..423316cdee07 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -962,7 +962,7 @@ static inline unsigned long group_weight(struct task_struct *p, int nid)
962 if (!total_faults) 962 if (!total_faults)
963 return 0; 963 return 0;
964 964
965 return 1200 * group_faults(p, nid) / total_faults; 965 return 1000 * group_faults(p, nid) / total_faults;
966} 966}
967 967
968static unsigned long weighted_cpuload(const int cpu); 968static unsigned long weighted_cpuload(const int cpu);
@@ -1068,16 +1068,34 @@ static void task_numa_compare(struct task_numa_env *env,
1068 1068
1069 /* 1069 /*
1070 * If dst and source tasks are in the same NUMA group, or not 1070 * If dst and source tasks are in the same NUMA group, or not
1071 * in any group then look only at task weights otherwise give 1071 * in any group then look only at task weights.
1072 * priority to the group weights.
1073 */ 1072 */
1074 if (!cur->numa_group || !env->p->numa_group || 1073 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) - 1074 imp = taskimp + task_weight(cur, env->src_nid) -
1077 task_weight(cur, env->dst_nid); 1075 task_weight(cur, env->dst_nid);
1076 /*
1077 * Add some hysteresis to prevent swapping the
1078 * tasks within a group over tiny differences.
1079 */
1080 if (cur->numa_group)
1081 imp -= imp/16;
1078 } else { 1082 } else {
1079 imp = groupimp + group_weight(cur, env->src_nid) - 1083 /*
1080 group_weight(cur, env->dst_nid); 1084 * Compare the group weights. If a task is all by
1085 * itself (not part of a group), use the task weight
1086 * instead.
1087 */
1088 if (env->p->numa_group)
1089 imp = groupimp;
1090 else
1091 imp = taskimp;
1092
1093 if (cur->numa_group)
1094 imp += group_weight(cur, env->src_nid) -
1095 group_weight(cur, env->dst_nid);
1096 else
1097 imp += task_weight(cur, env->src_nid) -
1098 task_weight(cur, env->dst_nid);
1081 } 1099 }
1082 } 1100 }
1083 1101