From: Erin Yang erin.yang@mstarsemi.com
From: Erin Yang erin.yang@mstarsemi.com
The two conditions, “target_capacity” and “target_max_spare_cap”, in find_best_target() are not enough to result in a good load balance within a cluster.
For example, there are 2 little (say core 0 & 1) and 2 big (say core 2 & 3) cores. The capacity of little and big cores are 500 and 1024, respectively. Step 1: A task with task_util 100 and boost value 50 comes. So, it starts from big cores. Finally, CPU 3 is selected. Step 2: A task with task_util 10 and boost value 50 comes. So, it starts from big cores. Finally, CPU 3 is selected again. If we add an extra condition, "target_max_free_util", CPU 2 can be selected instead at Step 2.
Assume current cpu utility is as follows. Capacity_orig cpu_util CPU 0 500 100 CPU 1 500 100 CPU 2 1024 100 CPU 3 1024 100
Step 2. A task with task_util 100 and boost value 50 comes. So, it starts from big cores. Finally, CPU 3 is selected. Capacity_orig cpu_util New_util target_max_spare_cap target_max_free_util CPU 0 500 100 562 (100 + (1024-100)*50% = 562) continued via “new_util > capacity_orig” CPU 1 500 100 562 continued via “new_util > capacity_orig” CPU 2 1024 100 562 462 924 CPU 3 1024 100 562 462 924 (CPU 3 is selected.)
Step 3. A task with task_util 10 and boost value 50 comes. So, it starts from big cores. Capacity_orig cpu_util New_util target_max_spare_cap target_max_free_util CPU 0 500 100 517 (10 + (1024-10)*50% = 517) continued via “new_util > capacity_orig” CPU 1 500 100 517 continued via “new_util > capacity_orig” CPU 2 1024 100 517 507 924 CPU 3 1024 200 517 507 824
to test it, this LISA notebook can create small boosted tasks with rtapp https://github.com/realmz/lisa/blob/hikey960_v3/ipynb/tests/max_free_util_te...
Change-Id: I0ef662e584e1e750381039a9a3941e43c37c221f Signed-off-by: Erin Yang erin.yang@mstarsemi.com ---
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index a146ac4..5abf50c 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -6697,6 +6697,7 @@ unsigned long target_max_spare_cap = 0; unsigned long target_util = ULONG_MAX; unsigned long best_active_util = ULONG_MAX; + unsigned long target_max_free_util = 0; int best_idle_cstate = INT_MAX; struct sched_domain *sd; struct sched_group *sg; @@ -6910,8 +6911,8 @@ * that CPU at an higher OPP. * * Thus, this case keep track of the CPU with the - * smallest maximum capacity and highest spare maximum - * capacity. + * smallest maximum capacity, highest spare maximum + * capacity and highest free cpu utility. */
/* Favor CPUs with smaller capacity */ @@ -6922,8 +6923,13 @@ if ((capacity_orig - new_util) < target_max_spare_cap) continue;
+ /* Favor CPUs with maximum free utilization */ + if ((capacity_orig - cpu_util(i)) < target_max_free_util) + continue; + target_max_spare_cap = capacity_orig - new_util; target_capacity = capacity_orig; + target_max_free_util = capacity_orig - cpu_util(i); target_util = new_util; target_cpu = i; } IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.