scx_lavd: fix uninitialized memory access comp_preemption_info()

The previous code accesses uninitialized memory in comp_preemption_info()
when called from can_task1_kick_task2() <-try_yield_current_cpu()
to test if a task 2 is a lock holder or not. However, task2 is guaranteed
not a lock holder in all its callers. So move the lock holder testing to
can_cpu1_kick_cpu2().

Signed-off-by: Changwoo Min <changwoo@igalia.com>
This commit is contained in:
Changwoo Min 2024-10-24 15:53:44 +09:00
parent 371020a096
commit 4f6947736f

View File

@ -21,12 +21,6 @@ static u64 get_est_stopping_time(struct task_ctx *taskc)
static int comp_preemption_info(struct preemption_info *prm_a,
struct preemption_info *prm_b)
{
/*
* Never preeempt a lock holder.
*/
if (prm_b->cpuc->lock_holder)
return 1;
/*
* Check if one's latency priority _or_ deadline is smaller or not.
*/
@ -42,6 +36,14 @@ static int comp_preemption_info(struct preemption_info *prm_a,
static bool can_task1_kick_task2(struct preemption_info *prm_task1,
struct preemption_info *prm_task2)
{
/*
* A caller should ensure that task2 is not a lock holder.
*/
/*
* If that CPU runs a lower priority task, that's a victim
* candidate.
*/
return comp_preemption_info(prm_task1, prm_task2) < 0;
}
@ -57,11 +59,17 @@ static bool can_cpu1_kick_cpu2(struct preemption_info *prm_cpu1,
prm_cpu2->cpuc = cpuc2;
prm_cpu2->last_kick_clk = cpuc2->last_kick_clk;
/*
* Never preeempt a CPU running a lock holder.
*/
if (prm_cpu2->cpuc->lock_holder)
return false;
/*
* If that CPU runs a lower priority task, that's a victim
* candidate.
*/
return can_task1_kick_task2(prm_cpu1, prm_cpu2);
return comp_preemption_info(prm_cpu1, prm_cpu2) < 0;
}
static bool is_worth_kick_other_task(struct task_ctx *taskc)
@ -168,6 +176,9 @@ static struct cpu_ctx *find_victim_cpu(const struct cpumask *cpumask,
/*
* If that CPU runs a lower priority task, that's a victim
* candidate.
*
* Note that a task running on cpu 2 (prm_cpus[v]) cannot
* be a lock holder.
*/
ret = can_cpu1_kick_cpu2(&prm_task, &prm_cpus[v], cpuc);
if (ret == true && ++v >= 2)
@ -178,7 +189,7 @@ static struct cpu_ctx *find_victim_cpu(const struct cpumask *cpumask,
* Choose a final victim CPU.
*/
switch(v) {
case 2: /* two dandidates */
case 2: /* two candidates */
victim_cpu = can_task1_kick_task2(&prm_cpus[0], &prm_cpus[1]) ?
&prm_cpus[0] : &prm_cpus[1];
goto bingo_out;