kernel/sched/walt: start domain rebuilding and wait

There is a race condition in cpufreq.c in which the energy model
is not updated until after rebuild domains has completed. If
this is performed out of order, the rebuild domains will fail and
the perf domains will be freed, causing
walt_find_energy_efficient_cpu to fail to perform active migration.

After topology update is complete and walt initialization moves
forward, rebuild the domains waiting for the completion of the
rebuild before performing the walt update of the toplogy,
guranteeing that the perf domains are populated properly even if
cpufreq builds the domains the first time, out of order.

Change-Id: I28499c4318580da54735347be0ea00867e68d94b
Signed-off-by: Stephen Dickey <quic_dickey@quicinc.com>
This commit is contained in:
Stephen Dickey 2022-08-17 16:53:00 -07:00 committed by Sai Harshini Nimmala
parent 2b0465b6c3
commit 427c7e27f6
2 changed files with 11 additions and 0 deletions

View File

@ -4440,6 +4440,14 @@ static void android_rvh_build_perf_domains(void *unused, bool *eas_check)
*eas_check = true;
}
static DECLARE_COMPLETION(rebuild_domains_completion);
static void rebuild_sd_workfn(struct work_struct *work)
{
rebuild_sched_domains();
complete(&rebuild_domains_completion);
}
static DECLARE_WORK(rebuild_sd_work, rebuild_sd_workfn);
static void walt_do_sched_yield(void *unused, struct rq *rq)
{
struct task_struct *curr = rq->curr;
@ -4573,6 +4581,8 @@ static void walt_init(struct work_struct *work)
walt_cfs_init();
walt_halt_init();
wait_for_completion_interruptible(&tick_sched_clock_completion);
schedule_work(&rebuild_sd_work);
wait_for_completion_interruptible(&rebuild_domains_completion);
stop_machine(walt_init_stop_handler, NULL, NULL);
hdr = register_sysctl_table(walt_base_table);

View File

@ -189,6 +189,7 @@ extern void walt_init_foreground_tg(struct task_group *tg);
extern int register_walt_callback(void);
extern int input_boost_init(void);
extern int core_ctl_init(void);
extern void rebuild_sched_domains(void);
extern atomic64_t walt_irq_work_lastq_ws;
extern unsigned int __read_mostly sched_ravg_window;