Skip to content

Commit

Permalink
sched: pull only one task during NEWIDLE balancing to limit critical …
Browse files Browse the repository at this point in the history
…section

git-id c4acb2c attempted to limit
newidle critical section length by stopping after at least one task
was moved.  Further investigation has shown that there are other
paths nested further inside the algorithm which still remain that allow
long latencies to occur with newidle balancing.  This patch applies
the same technique inside balance_tasks() to limit the duration of
this optional balancing operation.

Signed-off-by: Gregory Haskins <ghaskins@novell.com>
CC: Nick Piggin <npiggin@suse.de>
  • Loading branch information
Gregory Haskins committed Dec 29, 2008
1 parent 777c2f3 commit 7e96fa5
Showing 1 changed file with 17 additions and 1 deletion.
18 changes: 17 additions & 1 deletion kernel/sched.c
Original file line number Diff line number Diff line change
Expand Up @@ -2984,6 +2984,16 @@ balance_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest,
pulled++;
rem_load_move -= p->se.load.weight;

#ifdef CONFIG_PREEMPT
/*
* NEWIDLE balancing is a source of latency, so preemptible kernels
* will stop after the first task is pulled to minimize the critical
* section.
*/
if (idle == CPU_NEWLY_IDLE)
goto out;
#endif

/*
* We only want to steal up to the prescribed amount of weighted load.
*/
Expand Down Expand Up @@ -3030,9 +3040,15 @@ static int move_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest,
sd, idle, all_pinned, &this_best_prio);
class = class->next;

#ifdef CONFIG_PREEMPT
/*
* NEWIDLE balancing is a source of latency, so preemptible
* kernels will stop after the first task is pulled to minimize
* the critical section.
*/
if (idle == CPU_NEWLY_IDLE && this_rq->nr_running)
break;

#endif
} while (class && max_load_move > total_load_moved);

return total_load_moved > 0;
Expand Down

0 comments on commit 7e96fa5

Please sign in to comment.