aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/sched/fair.c22
-rw-r--r--kernel/sched/sched.h1
2 files changed, 23 insertions, 0 deletions
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index f808ddf2a868..3b0b75de1141 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -1514,6 +1514,21 @@ struct task_numa_env {
1514static void task_numa_assign(struct task_numa_env *env, 1514static void task_numa_assign(struct task_numa_env *env,
1515 struct task_struct *p, long imp) 1515 struct task_struct *p, long imp)
1516{ 1516{
1517 struct rq *rq = cpu_rq(env->dst_cpu);
1518
1519 /* Bail out if run-queue part of active NUMA balance. */
1520 if (xchg(&rq->numa_migrate_on, 1))
1521 return;
1522
1523 /*
1524 * Clear previous best_cpu/rq numa-migrate flag, since task now
1525 * found a better CPU to move/swap.
1526 */
1527 if (env->best_cpu != -1) {
1528 rq = cpu_rq(env->best_cpu);
1529 WRITE_ONCE(rq->numa_migrate_on, 0);
1530 }
1531
1517 if (env->best_task) 1532 if (env->best_task)
1518 put_task_struct(env->best_task); 1533 put_task_struct(env->best_task);
1519 if (p) 1534 if (p)
@@ -1569,6 +1584,9 @@ static void task_numa_compare(struct task_numa_env *env,
1569 long moveimp = imp; 1584 long moveimp = imp;
1570 int dist = env->dist; 1585 int dist = env->dist;
1571 1586
1587 if (READ_ONCE(dst_rq->numa_migrate_on))
1588 return;
1589
1572 rcu_read_lock(); 1590 rcu_read_lock();
1573 cur = task_rcu_dereference(&dst_rq->curr); 1591 cur = task_rcu_dereference(&dst_rq->curr);
1574 if (cur && ((cur->flags & PF_EXITING) || is_idle_task(cur))) 1592 if (cur && ((cur->flags & PF_EXITING) || is_idle_task(cur)))
@@ -1710,6 +1728,7 @@ static int task_numa_migrate(struct task_struct *p)
1710 .best_cpu = -1, 1728 .best_cpu = -1,
1711 }; 1729 };
1712 struct sched_domain *sd; 1730 struct sched_domain *sd;
1731 struct rq *best_rq;
1713 unsigned long taskweight, groupweight; 1732 unsigned long taskweight, groupweight;
1714 int nid, ret, dist; 1733 int nid, ret, dist;
1715 long taskimp, groupimp; 1734 long taskimp, groupimp;
@@ -1811,14 +1830,17 @@ static int task_numa_migrate(struct task_struct *p)
1811 */ 1830 */
1812 p->numa_scan_period = task_scan_start(p); 1831 p->numa_scan_period = task_scan_start(p);
1813 1832
1833 best_rq = cpu_rq(env.best_cpu);
1814 if (env.best_task == NULL) { 1834 if (env.best_task == NULL) {
1815 ret = migrate_task_to(p, env.best_cpu); 1835 ret = migrate_task_to(p, env.best_cpu);
1836 WRITE_ONCE(best_rq->numa_migrate_on, 0);
1816 if (ret != 0) 1837 if (ret != 0)
1817 trace_sched_stick_numa(p, env.src_cpu, env.best_cpu); 1838 trace_sched_stick_numa(p, env.src_cpu, env.best_cpu);
1818 return ret; 1839 return ret;
1819 } 1840 }
1820 1841
1821 ret = migrate_swap(p, env.best_task, env.best_cpu, env.src_cpu); 1842 ret = migrate_swap(p, env.best_task, env.best_cpu, env.src_cpu);
1843 WRITE_ONCE(best_rq->numa_migrate_on, 0);
1822 1844
1823 if (ret != 0) 1845 if (ret != 0)
1824 trace_sched_stick_numa(p, env.src_cpu, task_cpu(env.best_task)); 1846 trace_sched_stick_numa(p, env.src_cpu, task_cpu(env.best_task));
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index 4a2e8cae63c4..0b9161241bda 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -783,6 +783,7 @@ struct rq {
783#ifdef CONFIG_NUMA_BALANCING 783#ifdef CONFIG_NUMA_BALANCING
784 unsigned int nr_numa_running; 784 unsigned int nr_numa_running;
785 unsigned int nr_preferred_running; 785 unsigned int nr_preferred_running;
786 unsigned int numa_migrate_on;
786#endif 787#endif
787 #define CPU_LOAD_IDX_MAX 5 788 #define CPU_LOAD_IDX_MAX 5
788 unsigned long cpu_load[CPU_LOAD_IDX_MAX]; 789 unsigned long cpu_load[CPU_LOAD_IDX_MAX];