[PATCH 9/13] less affine wakups

From: Nick Piggin
Date: Thu Feb 24 2005 - 02:34:53 EST


9/13

Do less affine wakeups. We're trying to reduce dbt2-pgsql idle time
regressions here... make sure we don't don't move tasks the wrong way
in an imbalance condition. Also, remove the cache coldness requirement
from the calculation - this seems to induce sharp cutoff points where
behaviour will suddenly change on some workloads if the load creeps
slightly over or under some point. It is good for periodic balancing
because in that case have otherwise have no other context to determine
what task to move.

But also make a minor tweak to "wake balancing" - the imbalance
tolerance is now set at half the domain's imbalance, so we get the
opportunity to do wake balancing before the more random periodic
rebalancing gets preformed.

Signed-off-by: Nick Piggin <nickpiggin@xxxxxxxxxxxx>

Index: linux-2.6/kernel/sched.c
===================================================================
--- linux-2.6.orig/kernel/sched.c 2005-02-24 17:39:06.808010844 +1100
+++ linux-2.6/kernel/sched.c 2005-02-24 17:43:37.734579478 +1100
@@ -1014,38 +1014,45 @@
int idx = this_sd->wake_idx;
unsigned int imbalance;

+ imbalance = 100 + (this_sd->imbalance_pct - 100) / 2;
+
load = source_load(cpu, idx);
this_load = target_load(this_cpu, idx);

- /*
- * If sync wakeup then subtract the (maximum possible) effect of
- * the currently running task from the load of the current CPU:
- */
- if (sync)
- this_load -= SCHED_LOAD_SCALE;
-
- /* Don't pull the task off an idle CPU to a busy one */
- if (load < SCHED_LOAD_SCALE/2 && this_load > SCHED_LOAD_SCALE/2)
- goto out_set_cpu;
-
new_cpu = this_cpu; /* Wake to this CPU if we can */

- if ((this_sd->flags & SD_WAKE_AFFINE) &&
- !task_hot(p, rq->timestamp_last_tick, this_sd)) {
- /*
- * This domain has SD_WAKE_AFFINE and p is cache cold
- * in this domain.
- */
- schedstat_inc(this_sd, ttwu_move_affine);
- goto out_set_cpu;
- } else if ((this_sd->flags & SD_WAKE_BALANCE) &&
- imbalance*this_load <= 100*load) {
+ if (this_sd->flags & SD_WAKE_AFFINE) {
+ unsigned long tl = this_load;
/*
- * This domain has SD_WAKE_BALANCE and there is
- * an imbalance.
+ * If sync wakeup then subtract the (maximum possible)
+ * effect of the currently running task from the load
+ * of the current CPU:
*/
- schedstat_inc(this_sd, ttwu_move_balance);
- goto out_set_cpu;
+ if (sync)
+ tl -= SCHED_LOAD_SCALE;
+
+ if ((tl <= load &&
+ tl + target_load(cpu, idx) <= SCHED_LOAD_SCALE) ||
+ 100*(tl + SCHED_LOAD_SCALE) <= imbalance*load) {
+ /*
+ * This domain has SD_WAKE_AFFINE and
+ * p is cache cold in this domain, and
+ * there is no bad imbalance.
+ */
+ schedstat_inc(this_sd, ttwu_move_affine);
+ goto out_set_cpu;
+ }
+ }
+
+ /*
+ * Start passive balancing when half the imbalance_pct
+ * limit is reached.
+ */
+ if (this_sd->flags & SD_WAKE_BALANCE) {
+ if (imbalance*this_load <= 100*load) {
+ schedstat_inc(this_sd, ttwu_move_balance);
+ goto out_set_cpu;
+ }
}
}