Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fa3b6ddc authored by Siddha, Suresh B's avatar Siddha, Suresh B Committed by Linus Torvalds
Browse files

[PATCH] sched: don't kick ALB in the presence of pinned task



Jack Steiner brought this issue at my OLS talk.

Take a scenario where two tasks are pinned to two HT threads in a physical
package.  Idle packages in the system will keep kicking migration_thread on
the busy package with out any success.

We will run into similar scenarios in the presence of CMP/NUMA.

Signed-off-by: default avatarSuresh Siddha <suresh.b.siddha@intel.com>
Acked-by: default avatarIngo Molnar <mingo@elte.hu>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 5927ad78
Loading
Loading
Loading
Loading
+14 −1
Original line number Original line Diff line number Diff line
@@ -2125,6 +2125,16 @@ static int load_balance(int this_cpu, runqueue_t *this_rq,
		if (unlikely(sd->nr_balance_failed > sd->cache_nice_tries+2)) {
		if (unlikely(sd->nr_balance_failed > sd->cache_nice_tries+2)) {


			spin_lock(&busiest->lock);
			spin_lock(&busiest->lock);

			/* don't kick the migration_thread, if the curr
			 * task on busiest cpu can't be moved to this_cpu
			 */
			if (!cpu_isset(this_cpu, busiest->curr->cpus_allowed)) {
				spin_unlock(&busiest->lock);
				all_pinned = 1;
				goto out_one_pinned;
			}

			if (!busiest->active_balance) {
			if (!busiest->active_balance) {
				busiest->active_balance = 1;
				busiest->active_balance = 1;
				busiest->push_cpu = this_cpu;
				busiest->push_cpu = this_cpu;
@@ -2165,6 +2175,8 @@ static int load_balance(int this_cpu, runqueue_t *this_rq,
	schedstat_inc(sd, lb_balanced[idle]);
	schedstat_inc(sd, lb_balanced[idle]);


	sd->nr_balance_failed = 0;
	sd->nr_balance_failed = 0;

out_one_pinned:
	/* tune up the balancing interval */
	/* tune up the balancing interval */
	if ((all_pinned && sd->balance_interval < MAX_PINNED_INTERVAL) ||
	if ((all_pinned && sd->balance_interval < MAX_PINNED_INTERVAL) ||
			(sd->balance_interval < sd->max_interval))
			(sd->balance_interval < sd->max_interval))
@@ -2357,7 +2369,8 @@ static void rebalance_tick(int this_cpu, runqueue_t *this_rq,


		if (j - sd->last_balance >= interval) {
		if (j - sd->last_balance >= interval) {
			if (load_balance(this_cpu, this_rq, sd, idle)) {
			if (load_balance(this_cpu, this_rq, sd, idle)) {
				/* We've pulled tasks over so either we're no
				/*
				 * We've pulled tasks over so either we're no
				 * longer idle, or one of our SMT siblings is
				 * longer idle, or one of our SMT siblings is
				 * not idle.
				 * not idle.
				 */
				 */