|
@@ -4107,12 +4107,43 @@ static bool migrate_improves_locality(struct task_struct *p, struct lb_env *env)
|
|
|
|
|
|
return false;
|
|
|
}
|
|
|
+
|
|
|
+
|
|
|
+static bool migrate_degrades_locality(struct task_struct *p, struct lb_env *env)
|
|
|
+{
|
|
|
+ int src_nid, dst_nid;
|
|
|
+
|
|
|
+ if (!sched_feat(NUMA) || !sched_feat(NUMA_RESIST_LOWER))
|
|
|
+ return false;
|
|
|
+
|
|
|
+ if (!p->numa_faults || !(env->sd->flags & SD_NUMA))
|
|
|
+ return false;
|
|
|
+
|
|
|
+ src_nid = cpu_to_node(env->src_cpu);
|
|
|
+ dst_nid = cpu_to_node(env->dst_cpu);
|
|
|
+
|
|
|
+ if (src_nid == dst_nid ||
|
|
|
+ p->numa_migrate_seq >= sysctl_numa_balancing_settle_count)
|
|
|
+ return false;
|
|
|
+
|
|
|
+ if (p->numa_faults[dst_nid] < p->numa_faults[src_nid])
|
|
|
+ return true;
|
|
|
+
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
#else
|
|
|
static inline bool migrate_improves_locality(struct task_struct *p,
|
|
|
struct lb_env *env)
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
+
|
|
|
+static inline bool migrate_degrades_locality(struct task_struct *p,
|
|
|
+ struct lb_env *env)
|
|
|
+{
|
|
|
+ return false;
|
|
|
+}
|
|
|
#endif
|
|
|
|
|
|
/*
|
|
@@ -4177,6 +4208,8 @@ int can_migrate_task(struct task_struct *p, struct lb_env *env)
|
|
|
* 3) too many balance attempts have failed.
|
|
|
*/
|
|
|
tsk_cache_hot = task_hot(p, rq_clock_task(env->src_rq), env->sd);
|
|
|
+ if (!tsk_cache_hot)
|
|
|
+ tsk_cache_hot = migrate_degrades_locality(p, env);
|
|
|
|
|
|
if (migrate_improves_locality(p, env)) {
|
|
|
#ifdef CONFIG_SCHEDSTATS
|