Skip to content

Commit

Permalink
x86/percpu: Cure per CPU madness on UP
Browse files Browse the repository at this point in the history
On UP builds Sparse complains rightfully about accesses to cpu_info with
per CPU accessors:

  cacheinfo.c:282:30: sparse: warning: incorrect type in initializer (different address spaces)
  cacheinfo.c:282:30: sparse:    expected void const [noderef] __percpu *__vpp_verify
  cacheinfo.c:282:30: sparse:    got unsigned int *

The reason is that on UP builds cpu_info which is a per CPU variable on SMP
is mapped to boot_cpu_info which is a regular variable. There is a hideous
accessor cpu_data() which tries to hide this, but it's not sufficient as
some places require raw accessors and generates worse code than the regular
per CPU accessors.

Waste sizeof(struct x86_cpuinfo) memory on UP and provide the per CPU
cpu_info unconditionally. This requires to update the CPU info on the boot
CPU as SMP does. (Ab)use the weakly defined smp_prepare_boot_cpu() function
and implement exactly that.

This allows to use regular per CPU accessors uncoditionally and paves the
way to remove the cpu_data() hackery.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Link: https://lore.kernel.org/r/20240304005104.622511517@linutronix.de
  • Loading branch information
KAGA-KOKO authored and Ingo Molnar committed Mar 4, 2024
1 parent 7126107 commit 71eb489
Show file tree
Hide file tree
Showing 4 changed files with 13 additions and 9 deletions.
5 changes: 0 additions & 5 deletions arch/x86/include/asm/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -185,13 +185,8 @@ extern struct cpuinfo_x86 new_cpu_data;
extern __u32 cpu_caps_cleared[NCAPINTS + NBUGINTS];
extern __u32 cpu_caps_set[NCAPINTS + NBUGINTS];

#ifdef CONFIG_SMP
DECLARE_PER_CPU_READ_MOSTLY(struct cpuinfo_x86, cpu_info);
#define cpu_data(cpu) per_cpu(cpu_info, cpu)
#else
#define cpu_info boot_cpu_data
#define cpu_data(cpu) boot_cpu_data
#endif

extern const struct seq_operations cpuinfo_op;

Expand Down
3 changes: 3 additions & 0 deletions arch/x86/kernel/cpu/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@

#include "cpu.h"

DEFINE_PER_CPU_READ_MOSTLY(struct cpuinfo_x86, cpu_info);
EXPORT_PER_CPU_SYMBOL(cpu_info);

u32 elf_hwcap2 __read_mostly;

/* Number of siblings per CPU package */
Expand Down
10 changes: 10 additions & 0 deletions arch/x86/kernel/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -1211,6 +1211,16 @@ void __init i386_reserve_resources(void)

#endif /* CONFIG_X86_32 */

#ifndef CONFIG_SMP
void __init smp_prepare_boot_cpu(void)
{
struct cpuinfo_x86 *c = &cpu_data(0);

*c = boot_cpu_data;
c->initialized = true;
}
#endif

static struct notifier_block kernel_offset_notifier = {
.notifier_call = dump_kernel_offset
};
Expand Down
4 changes: 0 additions & 4 deletions arch/x86/kernel/smpboot.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,10 +101,6 @@ EXPORT_PER_CPU_SYMBOL(cpu_core_map);
DEFINE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_die_map);
EXPORT_PER_CPU_SYMBOL(cpu_die_map);

/* Per CPU bogomips and other parameters */
DEFINE_PER_CPU_READ_MOSTLY(struct cpuinfo_x86, cpu_info);
EXPORT_PER_CPU_SYMBOL(cpu_info);

/* CPUs which are the primary SMT threads */
struct cpumask __cpu_primary_thread_mask __read_mostly;

Expand Down

0 comments on commit 71eb489

Please sign in to comment.