mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-05-24 10:39:52 +00:00
x86/percpu: Cure per CPU madness on UP
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
This commit is contained in:
parent
712610725c
commit
71eb4893cf
4 changed files with 13 additions and 9 deletions
|
@ -185,13 +185,8 @@ extern struct cpuinfo_x86 new_cpu_data;
|
||||||
extern __u32 cpu_caps_cleared[NCAPINTS + NBUGINTS];
|
extern __u32 cpu_caps_cleared[NCAPINTS + NBUGINTS];
|
||||||
extern __u32 cpu_caps_set[NCAPINTS + NBUGINTS];
|
extern __u32 cpu_caps_set[NCAPINTS + NBUGINTS];
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
DECLARE_PER_CPU_READ_MOSTLY(struct cpuinfo_x86, cpu_info);
|
DECLARE_PER_CPU_READ_MOSTLY(struct cpuinfo_x86, cpu_info);
|
||||||
#define cpu_data(cpu) per_cpu(cpu_info, cpu)
|
#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;
|
extern const struct seq_operations cpuinfo_op;
|
||||||
|
|
||||||
|
|
|
@ -70,6 +70,9 @@
|
||||||
|
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
|
|
||||||
|
DEFINE_PER_CPU_READ_MOSTLY(struct cpuinfo_x86, cpu_info);
|
||||||
|
EXPORT_PER_CPU_SYMBOL(cpu_info);
|
||||||
|
|
||||||
u32 elf_hwcap2 __read_mostly;
|
u32 elf_hwcap2 __read_mostly;
|
||||||
|
|
||||||
/* Number of siblings per CPU package */
|
/* Number of siblings per CPU package */
|
||||||
|
|
|
@ -1211,6 +1211,16 @@ void __init i386_reserve_resources(void)
|
||||||
|
|
||||||
#endif /* CONFIG_X86_32 */
|
#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 = {
|
static struct notifier_block kernel_offset_notifier = {
|
||||||
.notifier_call = dump_kernel_offset
|
.notifier_call = dump_kernel_offset
|
||||||
};
|
};
|
||||||
|
|
|
@ -101,10 +101,6 @@ EXPORT_PER_CPU_SYMBOL(cpu_core_map);
|
||||||
DEFINE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_die_map);
|
DEFINE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_die_map);
|
||||||
EXPORT_PER_CPU_SYMBOL(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 */
|
/* CPUs which are the primary SMT threads */
|
||||||
struct cpumask __cpu_primary_thread_mask __read_mostly;
|
struct cpumask __cpu_primary_thread_mask __read_mostly;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue