ANDROID: sched/fair: Attempt to improve throughput for asym cap systems
authorChris Redpath <chris.redpath@arm.com>
Fri, 1 Jun 2018 19:34:10 +0000 (20:34 +0100)
committerChris Redpath <chris.redpath@arm.com>
Wed, 18 Jul 2018 09:42:49 +0000 (10:42 +0100)
In some systems the capacity and group weights line up to defeat all the
small imbalance correction conditions in fix_small_imbalance, which can
cause bad task placement. Add a new condition if the existing code can't
see anything to fix:

If we have asymmetric capacity, and there are more tasks than CPUs in
the busiest group *and* there are less tasks than CPUs in the local group
then we try to pull something. There could be transient small tasks which
prevent this from working, but on the whole it is beneficial for those
systems with inconvenient capacity/cluster size relationships.

Signed-off-by: Chris Redpath <chris.redpath@arm.com>
Change-Id: Icf81cde215c082a61f816534b7990ccb70aee409

kernel/sched/fair.c

index 23c5ce715dcc8b3453a1378f2aa170f5d90e8e5f..e03ca45f5ccdb87fc038657a33ee090159a3e0d7 100644 (file)
@@ -9492,7 +9492,22 @@ void fix_small_imbalance(struct lb_env *env, struct sd_lb_stats *sds)
        capa_move /= SCHED_CAPACITY_SCALE;
 
        /* Move if we gain throughput */
-       if (capa_move > capa_now)
+       if (capa_move > capa_now) {
+               env->imbalance = busiest->load_per_task;
+               return;
+       }
+
+       /* We can't see throughput improvement with the load-based
+        * method, but it is possible depending upon group size and
+        * capacity range that there might still be an underutilized
+        * cpu available in an asymmetric capacity system. Do one last
+        * check just in case.
+        */
+       if (env->sd->flags & SD_ASYM_CPUCAPACITY &&
+           busiest->group_type == group_overloaded &&
+           busiest->sum_nr_running > busiest->group_weight &&
+           local->sum_nr_running < local->group_weight &&
+           local->group_capacity < busiest->group_capacity)
                env->imbalance = busiest->load_per_task;
 }