mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 09:36:22 +02:00
riscv: misaligned: Fix fast_unaligned_access_speed_key init
When booting with unaligned_scalar_speed=fast, fast_unaligned_access_speed_key is initialized incorrectly. The key is currently derived from the fast_misaligned_access cpumask, but that mask is only populated when the unaligned access speed probe runs. Specifying unaligned_scalar_speed=fast skips the probe entirely, leaving the mask uninitialized. The information tracked by fast_misaligned_access is already available in the misaligned_access_speed per-CPU variable. Use that to initialize fast_unaligned_access_speed_key instead and remove the redundant cpumask. Signed-off-by: Nam Cao <namcao@linutronix.de> Link: https://patch.msgid.link/2468816ceb433394099a00d7822f819745276b49.1780002199.git.namcao@linutronix.de Signed-off-by: Paul Walmsley <pjw@kernel.org>
This commit is contained in:
parent
bce35135fe
commit
d585018a92
|
|
@ -27,8 +27,6 @@ DEFINE_PER_CPU(long, vector_misaligned_access) = RISCV_HWPROBE_MISALIGNED_VECTOR
|
|||
static long unaligned_scalar_speed_param = RISCV_HWPROBE_MISALIGNED_SCALAR_UNKNOWN;
|
||||
static long unaligned_vector_speed_param = RISCV_HWPROBE_MISALIGNED_VECTOR_UNKNOWN;
|
||||
|
||||
static cpumask_t fast_misaligned_access;
|
||||
|
||||
static u64 __maybe_unused
|
||||
measure_cycles(void (*func)(void *dst, const void *src, size_t len),
|
||||
void *dst, void *src, size_t len)
|
||||
|
|
@ -131,13 +129,10 @@ static int check_unaligned_access(struct page *page)
|
|||
* Set the value of fast_misaligned_access of a CPU. These operations
|
||||
* are atomic to avoid race conditions.
|
||||
*/
|
||||
if (ret) {
|
||||
if (ret)
|
||||
per_cpu(misaligned_access_speed, cpu) = RISCV_HWPROBE_MISALIGNED_SCALAR_FAST;
|
||||
cpumask_set_cpu(cpu, &fast_misaligned_access);
|
||||
} else {
|
||||
else
|
||||
per_cpu(misaligned_access_speed, cpu) = RISCV_HWPROBE_MISALIGNED_SCALAR_SLOW;
|
||||
cpumask_clear_cpu(cpu, &fast_misaligned_access);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -192,49 +187,24 @@ static void __init check_unaligned_access_speed_all_cpus(void)
|
|||
|
||||
DEFINE_STATIC_KEY_FALSE(fast_unaligned_access_speed_key);
|
||||
|
||||
static void modify_unaligned_access_branches(cpumask_t *mask, int weight)
|
||||
static void modify_unaligned_access_branches(const cpumask_t *mask)
|
||||
{
|
||||
if (cpumask_weight(mask) == weight)
|
||||
bool fast = true;
|
||||
int cpu;
|
||||
|
||||
for_each_cpu(cpu, mask) {
|
||||
if (per_cpu(misaligned_access_speed, cpu) != RISCV_HWPROBE_MISALIGNED_SCALAR_FAST) {
|
||||
fast = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (fast)
|
||||
static_branch_enable_cpuslocked(&fast_unaligned_access_speed_key);
|
||||
else
|
||||
static_branch_disable_cpuslocked(&fast_unaligned_access_speed_key);
|
||||
}
|
||||
|
||||
static void set_unaligned_access_static_branches_except_cpu(int cpu)
|
||||
{
|
||||
/*
|
||||
* Same as set_unaligned_access_static_branches, except excludes the
|
||||
* given CPU from the result. When a CPU is hotplugged into an offline
|
||||
* state, this function is called before the CPU is set to offline in
|
||||
* the cpumask, and thus the CPU needs to be explicitly excluded.
|
||||
*/
|
||||
|
||||
cpumask_t fast_except_me;
|
||||
|
||||
cpumask_and(&fast_except_me, &fast_misaligned_access, cpu_online_mask);
|
||||
cpumask_clear_cpu(cpu, &fast_except_me);
|
||||
|
||||
modify_unaligned_access_branches(&fast_except_me, num_online_cpus() - 1);
|
||||
}
|
||||
|
||||
static void set_unaligned_access_static_branches(void)
|
||||
{
|
||||
/*
|
||||
* This will be called after check_unaligned_access_all_cpus so the
|
||||
* result of unaligned access speed for all CPUs will be available.
|
||||
*
|
||||
* To avoid the number of online cpus changing between reading
|
||||
* cpu_online_mask and calling num_online_cpus, cpus_read_lock must be
|
||||
* held before calling this function.
|
||||
*/
|
||||
|
||||
cpumask_t fast_and_online;
|
||||
|
||||
cpumask_and(&fast_and_online, &fast_misaligned_access, cpu_online_mask);
|
||||
|
||||
modify_unaligned_access_branches(&fast_and_online, num_online_cpus());
|
||||
}
|
||||
|
||||
static int riscv_online_cpu(unsigned int cpu)
|
||||
{
|
||||
int ret = cpu_online_unaligned_access_init(cpu);
|
||||
|
|
@ -266,14 +236,19 @@ static int riscv_online_cpu(unsigned int cpu)
|
|||
#endif
|
||||
|
||||
exit:
|
||||
set_unaligned_access_static_branches();
|
||||
modify_unaligned_access_branches(cpu_online_mask);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int riscv_offline_cpu(unsigned int cpu)
|
||||
{
|
||||
set_unaligned_access_static_branches_except_cpu(cpu);
|
||||
cpumask_t mask;
|
||||
|
||||
cpumask_copy(&mask, cpu_online_mask);
|
||||
cpumask_clear_cpu(cpu, &mask);
|
||||
|
||||
modify_unaligned_access_branches(&mask);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -430,7 +405,7 @@ static int __init check_unaligned_access_all_cpus(void)
|
|||
riscv_online_cpu_vec, NULL);
|
||||
|
||||
cpus_read_lock();
|
||||
set_unaligned_access_static_branches();
|
||||
modify_unaligned_access_branches(cpu_online_mask);
|
||||
cpus_read_unlock();
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user