Skip to content

Commit b9655e7

Browse files
committed
x86/cpu: Encapsulate topology information in cpuinfo_x86
The topology related information is randomly scattered across cpuinfo_x86. Create a new structure cpuinfo_topo and move in a first step initial_apicid and apicid into it. Aside of being better readable this is in preparation for replacing the horribly fragile CPU topology evaluation code further down the road. Consolidate APIC ID fields to u32 as that represents the hardware type. No functional change. Signed-off-by: Thomas Gleixner <[email protected]> Tested-by: Juergen Gross <[email protected]> Tested-by: Sohil Mehta <[email protected]> Tested-by: Michael Kelley <[email protected]> Tested-by: Peter Zijlstra (Intel) <[email protected]> Tested-by: Zhang Rui <[email protected]> Acked-by: Peter Zijlstra (Intel) <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 965e05f commit b9655e7

File tree

12 files changed

+52
-48
lines changed

12 files changed

+52
-48
lines changed

arch/x86/include/asm/processor.h

+9-5
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,16 @@ extern u16 __read_mostly tlb_lld_4m[NR_INFO];
7575
extern u16 __read_mostly tlb_lld_1g[NR_INFO];
7676

7777
/*
78-
* CPU type and hardware bug flags. Kept separately for each CPU.
79-
* Members of this structure are referenced in head_32.S, so think twice
80-
* before touching them. [mj]
78+
* CPU type and hardware bug flags. Kept separately for each CPU.
8179
*/
8280

81+
struct cpuinfo_topology {
82+
// Real APIC ID read from the local APIC
83+
u32 apicid;
84+
// The initial APIC ID provided by CPUID
85+
u32 initial_apicid;
86+
};
87+
8388
struct cpuinfo_x86 {
8489
__u8 x86; /* CPU family */
8590
__u8 x86_vendor; /* CPU vendor */
@@ -112,6 +117,7 @@ struct cpuinfo_x86 {
112117
};
113118
char x86_vendor_id[16];
114119
char x86_model_id[64];
120+
struct cpuinfo_topology topo;
115121
/* in KB - valid for CPUS which support this call: */
116122
unsigned int x86_cache_size;
117123
int x86_cache_alignment; /* In bytes */
@@ -125,8 +131,6 @@ struct cpuinfo_x86 {
125131
u64 ppin;
126132
/* cpuid returned max cores value: */
127133
u16 x86_max_cores;
128-
u16 apicid;
129-
u16 initial_apicid;
130134
u16 x86_clflush_size;
131135
/* number of cores as seen by the OS: */
132136
u16 booted_cores;

arch/x86/kernel/cpu/amd.c

+5-5
Original file line numberDiff line numberDiff line change
@@ -459,9 +459,9 @@ static void amd_detect_cmp(struct cpuinfo_x86 *c)
459459

460460
bits = c->x86_coreid_bits;
461461
/* Low order bits define the core id (index of core in socket) */
462-
c->cpu_core_id = c->initial_apicid & ((1 << bits)-1);
462+
c->cpu_core_id = c->topo.initial_apicid & ((1 << bits)-1);
463463
/* Convert the initial APIC ID into the socket ID */
464-
c->phys_proc_id = c->initial_apicid >> bits;
464+
c->phys_proc_id = c->topo.initial_apicid >> bits;
465465
/* use socket ID also for last level cache */
466466
per_cpu(cpu_llc_id, cpu) = c->cpu_die_id = c->phys_proc_id;
467467
}
@@ -477,7 +477,7 @@ static void srat_detect_node(struct cpuinfo_x86 *c)
477477
#ifdef CONFIG_NUMA
478478
int cpu = smp_processor_id();
479479
int node;
480-
unsigned apicid = c->apicid;
480+
unsigned apicid = c->topo.apicid;
481481

482482
node = numa_cpu_node(cpu);
483483
if (node == NUMA_NO_NODE)
@@ -511,7 +511,7 @@ static void srat_detect_node(struct cpuinfo_x86 *c)
511511
* through CPU mapping may alter the outcome, directly
512512
* access __apicid_to_node[].
513513
*/
514-
int ht_nodeid = c->initial_apicid;
514+
int ht_nodeid = c->topo.initial_apicid;
515515

516516
if (__apicid_to_node[ht_nodeid] != NUMA_NO_NODE)
517517
node = __apicid_to_node[ht_nodeid];
@@ -1047,7 +1047,7 @@ static void init_amd(struct cpuinfo_x86 *c)
10471047
set_cpu_cap(c, X86_FEATURE_FSRS);
10481048

10491049
/* get apicid instead of initial apic id from cpuid */
1050-
c->apicid = read_apic_id();
1050+
c->topo.apicid = read_apic_id();
10511051

10521052
/* K6s reports MCEs but don't actually have all the MSRs */
10531053
if (c->x86 < 6)

arch/x86/kernel/cpu/cacheinfo.c

+10-10
Original file line numberDiff line numberDiff line change
@@ -678,7 +678,7 @@ void cacheinfo_amd_init_llc_id(struct cpuinfo_x86 *c, int cpu)
678678
* LLC is at the core complex level.
679679
* Core complex ID is ApicId[3] for these processors.
680680
*/
681-
per_cpu(cpu_llc_id, cpu) = c->apicid >> 3;
681+
per_cpu(cpu_llc_id, cpu) = c->topo.apicid >> 3;
682682
} else {
683683
/*
684684
* LLC ID is calculated from the number of threads sharing the
@@ -694,7 +694,7 @@ void cacheinfo_amd_init_llc_id(struct cpuinfo_x86 *c, int cpu)
694694
if (num_sharing_cache) {
695695
int bits = get_count_order(num_sharing_cache);
696696

697-
per_cpu(cpu_llc_id, cpu) = c->apicid >> bits;
697+
per_cpu(cpu_llc_id, cpu) = c->topo.apicid >> bits;
698698
}
699699
}
700700
}
@@ -712,7 +712,7 @@ void cacheinfo_hygon_init_llc_id(struct cpuinfo_x86 *c, int cpu)
712712
* LLC is at the core complex level.
713713
* Core complex ID is ApicId[3] for these processors.
714714
*/
715-
per_cpu(cpu_llc_id, cpu) = c->apicid >> 3;
715+
per_cpu(cpu_llc_id, cpu) = c->topo.apicid >> 3;
716716
}
717717

718718
void init_amd_cacheinfo(struct cpuinfo_x86 *c)
@@ -776,13 +776,13 @@ void init_intel_cacheinfo(struct cpuinfo_x86 *c)
776776
new_l2 = this_leaf.size/1024;
777777
num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing;
778778
index_msb = get_count_order(num_threads_sharing);
779-
l2_id = c->apicid & ~((1 << index_msb) - 1);
779+
l2_id = c->topo.apicid & ~((1 << index_msb) - 1);
780780
break;
781781
case 3:
782782
new_l3 = this_leaf.size/1024;
783783
num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing;
784784
index_msb = get_count_order(num_threads_sharing);
785-
l3_id = c->apicid & ~((1 << index_msb) - 1);
785+
l3_id = c->topo.apicid & ~((1 << index_msb) - 1);
786786
break;
787787
default:
788788
break;
@@ -915,7 +915,7 @@ static int __cache_amd_cpumap_setup(unsigned int cpu, int index,
915915
unsigned int apicid, nshared, first, last;
916916

917917
nshared = base->eax.split.num_threads_sharing + 1;
918-
apicid = cpu_data(cpu).apicid;
918+
apicid = cpu_data(cpu).topo.apicid;
919919
first = apicid - (apicid % nshared);
920920
last = first + nshared - 1;
921921

@@ -924,14 +924,14 @@ static int __cache_amd_cpumap_setup(unsigned int cpu, int index,
924924
if (!this_cpu_ci->info_list)
925925
continue;
926926

927-
apicid = cpu_data(i).apicid;
927+
apicid = cpu_data(i).topo.apicid;
928928
if ((apicid < first) || (apicid > last))
929929
continue;
930930

931931
this_leaf = this_cpu_ci->info_list + index;
932932

933933
for_each_online_cpu(sibling) {
934-
apicid = cpu_data(sibling).apicid;
934+
apicid = cpu_data(sibling).topo.apicid;
935935
if ((apicid < first) || (apicid > last))
936936
continue;
937937
cpumask_set_cpu(sibling,
@@ -969,7 +969,7 @@ static void __cache_cpumap_setup(unsigned int cpu, int index,
969969
index_msb = get_count_order(num_threads_sharing);
970970

971971
for_each_online_cpu(i)
972-
if (cpu_data(i).apicid >> index_msb == c->apicid >> index_msb) {
972+
if (cpu_data(i).topo.apicid >> index_msb == c->topo.apicid >> index_msb) {
973973
struct cpu_cacheinfo *sib_cpu_ci = get_cpu_cacheinfo(i);
974974

975975
if (i == cpu || !sib_cpu_ci->info_list)
@@ -1024,7 +1024,7 @@ static void get_cache_id(int cpu, struct _cpuid4_info_regs *id4_regs)
10241024

10251025
num_threads_sharing = 1 + id4_regs->eax.split.num_threads_sharing;
10261026
index_msb = get_count_order(num_threads_sharing);
1027-
id4_regs->id = c->apicid >> index_msb;
1027+
id4_regs->id = c->topo.apicid >> index_msb;
10281028
}
10291029

10301030
int populate_cache_leaves(unsigned int cpu)

arch/x86/kernel/cpu/common.c

+9-9
Original file line numberDiff line numberDiff line change
@@ -914,15 +914,15 @@ void detect_ht(struct cpuinfo_x86 *c)
914914
return;
915915

916916
index_msb = get_count_order(smp_num_siblings);
917-
c->phys_proc_id = apic->phys_pkg_id(c->initial_apicid, index_msb);
917+
c->phys_proc_id = apic->phys_pkg_id(c->topo.initial_apicid, index_msb);
918918

919919
smp_num_siblings = smp_num_siblings / c->x86_max_cores;
920920

921921
index_msb = get_count_order(smp_num_siblings);
922922

923923
core_bits = get_count_order(c->x86_max_cores);
924924

925-
c->cpu_core_id = apic->phys_pkg_id(c->initial_apicid, index_msb) &
925+
c->cpu_core_id = apic->phys_pkg_id(c->topo.initial_apicid, index_msb) &
926926
((1 << core_bits) - 1);
927927
#endif
928928
}
@@ -1761,15 +1761,15 @@ static void generic_identify(struct cpuinfo_x86 *c)
17611761
get_cpu_address_sizes(c);
17621762

17631763
if (c->cpuid_level >= 0x00000001) {
1764-
c->initial_apicid = (cpuid_ebx(1) >> 24) & 0xFF;
1764+
c->topo.initial_apicid = (cpuid_ebx(1) >> 24) & 0xFF;
17651765
#ifdef CONFIG_X86_32
17661766
# ifdef CONFIG_SMP
1767-
c->apicid = apic->phys_pkg_id(c->initial_apicid, 0);
1767+
c->topo.apicid = apic->phys_pkg_id(c->topo.initial_apicid, 0);
17681768
# else
1769-
c->apicid = c->initial_apicid;
1769+
c->topo.apicid = c->topo.initial_apicid;
17701770
# endif
17711771
#endif
1772-
c->phys_proc_id = c->initial_apicid;
1772+
c->phys_proc_id = c->topo.initial_apicid;
17731773
}
17741774

17751775
get_model_name(c); /* Default name */
@@ -1803,9 +1803,9 @@ static void validate_apic_and_package_id(struct cpuinfo_x86 *c)
18031803

18041804
apicid = apic->cpu_present_to_apicid(cpu);
18051805

1806-
if (apicid != c->apicid) {
1806+
if (apicid != c->topo.apicid) {
18071807
pr_err(FW_BUG "CPU%u: APIC id mismatch. Firmware: %x APIC: %x\n",
1808-
cpu, apicid, c->initial_apicid);
1808+
cpu, apicid, c->topo.initial_apicid);
18091809
}
18101810
BUG_ON(topology_update_package_map(c->phys_proc_id, cpu));
18111811
BUG_ON(topology_update_die_map(c->cpu_die_id, cpu));
@@ -1855,7 +1855,7 @@ static void identify_cpu(struct cpuinfo_x86 *c)
18551855
apply_forced_caps(c);
18561856

18571857
#ifdef CONFIG_X86_64
1858-
c->apicid = apic->phys_pkg_id(c->initial_apicid, 0);
1858+
c->topo.apicid = apic->phys_pkg_id(c->topo.initial_apicid, 0);
18591859
#endif
18601860

18611861
/*

arch/x86/kernel/cpu/hygon.c

+6-6
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ static void hygon_get_topology(struct cpuinfo_x86 *c)
9292
* when running on host.
9393
*/
9494
if (!boot_cpu_has(X86_FEATURE_HYPERVISOR) && c->x86_model <= 0x3)
95-
c->phys_proc_id = c->apicid >> APICID_SOCKET_ID_BIT;
95+
c->phys_proc_id = c->topo.apicid >> APICID_SOCKET_ID_BIT;
9696

9797
cacheinfo_hygon_init_llc_id(c, cpu);
9898
} else if (cpu_has(c, X86_FEATURE_NODEID_MSR)) {
@@ -120,9 +120,9 @@ static void hygon_detect_cmp(struct cpuinfo_x86 *c)
120120

121121
bits = c->x86_coreid_bits;
122122
/* Low order bits define the core id (index of core in socket) */
123-
c->cpu_core_id = c->initial_apicid & ((1 << bits)-1);
123+
c->cpu_core_id = c->topo.initial_apicid & ((1 << bits)-1);
124124
/* Convert the initial APIC ID into the socket ID */
125-
c->phys_proc_id = c->initial_apicid >> bits;
125+
c->phys_proc_id = c->topo.initial_apicid >> bits;
126126
/* use socket ID also for last level cache */
127127
per_cpu(cpu_llc_id, cpu) = c->cpu_die_id = c->phys_proc_id;
128128
}
@@ -132,7 +132,7 @@ static void srat_detect_node(struct cpuinfo_x86 *c)
132132
#ifdef CONFIG_NUMA
133133
int cpu = smp_processor_id();
134134
int node;
135-
unsigned int apicid = c->apicid;
135+
unsigned int apicid = c->topo.apicid;
136136

137137
node = numa_cpu_node(cpu);
138138
if (node == NUMA_NO_NODE)
@@ -165,7 +165,7 @@ static void srat_detect_node(struct cpuinfo_x86 *c)
165165
* through CPU mapping may alter the outcome, directly
166166
* access __apicid_to_node[].
167167
*/
168-
int ht_nodeid = c->initial_apicid;
168+
int ht_nodeid = c->topo.initial_apicid;
169169

170170
if (__apicid_to_node[ht_nodeid] != NUMA_NO_NODE)
171171
node = __apicid_to_node[ht_nodeid];
@@ -305,7 +305,7 @@ static void init_hygon(struct cpuinfo_x86 *c)
305305
set_cpu_cap(c, X86_FEATURE_REP_GOOD);
306306

307307
/* get apicid instead of initial apic id from cpuid */
308-
c->apicid = read_apic_id();
308+
c->topo.apicid = read_apic_id();
309309

310310
/*
311311
* XXX someone from Hygon needs to confirm this DTRT

arch/x86/kernel/cpu/mce/apei.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ int apei_smca_report_x86_error(struct cper_ia_proc_ctx *ctx_info, u64 lapic_id)
103103
m.socketid = -1;
104104

105105
for_each_possible_cpu(cpu) {
106-
if (cpu_data(cpu).initial_apicid == lapic_id) {
106+
if (cpu_data(cpu).topo.initial_apicid == lapic_id) {
107107
m.extcpu = cpu;
108108
m.socketid = cpu_data(m.extcpu).phys_proc_id;
109109
break;

arch/x86/kernel/cpu/mce/core.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ void mce_setup(struct mce *m)
124124
m->cpuvendor = boot_cpu_data.x86_vendor;
125125
m->cpuid = cpuid_eax(1);
126126
m->socketid = cpu_data(m->extcpu).phys_proc_id;
127-
m->apicid = cpu_data(m->extcpu).initial_apicid;
127+
m->apicid = cpu_data(m->extcpu).topo.initial_apicid;
128128
m->mcgcap = __rdmsr(MSR_IA32_MCG_CAP);
129129
m->ppin = cpu_data(m->extcpu).ppin;
130130
m->microcode = boot_cpu_data.microcode;

arch/x86/kernel/cpu/proc.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ static void show_cpuinfo_core(struct seq_file *m, struct cpuinfo_x86 *c,
2525
cpumask_weight(topology_core_cpumask(cpu)));
2626
seq_printf(m, "core id\t\t: %d\n", c->cpu_core_id);
2727
seq_printf(m, "cpu cores\t: %d\n", c->booted_cores);
28-
seq_printf(m, "apicid\t\t: %d\n", c->apicid);
29-
seq_printf(m, "initial apicid\t: %d\n", c->initial_apicid);
28+
seq_printf(m, "apicid\t\t: %d\n", c->topo.apicid);
29+
seq_printf(m, "initial apicid\t: %d\n", c->topo.initial_apicid);
3030
#endif
3131
}
3232

arch/x86/kernel/cpu/topology.c

+6-6
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ int detect_extended_topology_early(struct cpuinfo_x86 *c)
7878
/*
7979
* initial apic id, which also represents 32-bit extended x2apic id.
8080
*/
81-
c->initial_apicid = edx;
81+
c->topo.initial_apicid = edx;
8282
smp_num_siblings = max_t(int, smp_num_siblings, LEVEL_MAX_SIBLINGS(ebx));
8383
#endif
8484
return 0;
@@ -108,7 +108,7 @@ int detect_extended_topology(struct cpuinfo_x86 *c)
108108
* Populate HT related information from sub-leaf level 0.
109109
*/
110110
cpuid_count(leaf, SMT_LEVEL, &eax, &ebx, &ecx, &edx);
111-
c->initial_apicid = edx;
111+
c->topo.initial_apicid = edx;
112112
core_level_siblings = LEVEL_MAX_SIBLINGS(ebx);
113113
smp_num_siblings = max_t(int, smp_num_siblings, LEVEL_MAX_SIBLINGS(ebx));
114114
core_plus_mask_width = ht_mask_width = BITS_SHIFT_NEXT_LEVEL(eax);
@@ -146,20 +146,20 @@ int detect_extended_topology(struct cpuinfo_x86 *c)
146146
die_select_mask = (~(-1 << die_plus_mask_width)) >>
147147
core_plus_mask_width;
148148

149-
c->cpu_core_id = apic->phys_pkg_id(c->initial_apicid,
149+
c->cpu_core_id = apic->phys_pkg_id(c->topo.initial_apicid,
150150
ht_mask_width) & core_select_mask;
151151

152152
if (die_level_present) {
153-
c->cpu_die_id = apic->phys_pkg_id(c->initial_apicid,
153+
c->cpu_die_id = apic->phys_pkg_id(c->topo.initial_apicid,
154154
core_plus_mask_width) & die_select_mask;
155155
}
156156

157-
c->phys_proc_id = apic->phys_pkg_id(c->initial_apicid,
157+
c->phys_proc_id = apic->phys_pkg_id(c->topo.initial_apicid,
158158
pkg_mask_width);
159159
/*
160160
* Reinit the apicid, now that we have extended initial_apicid.
161161
*/
162-
c->apicid = apic->phys_pkg_id(c->initial_apicid, 0);
162+
c->topo.apicid = apic->phys_pkg_id(c->topo.initial_apicid, 0);
163163

164164
c->x86_max_cores = (core_level_siblings / smp_num_siblings);
165165
__max_die_per_package = (die_level_siblings / core_level_siblings);

arch/x86/xen/apic.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ static int xen_phys_pkg_id(int initial_apic_id, int index_msb)
118118
static int xen_cpu_present_to_apicid(int cpu)
119119
{
120120
if (cpu_present(cpu))
121-
return cpu_data(cpu).apicid;
121+
return cpu_data(cpu).topo.apicid;
122122
else
123123
return BAD_APICID;
124124
}

drivers/gpu/drm/amd/amdkfd/kfd_topology.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -2209,7 +2209,7 @@ static int kfd_cpumask_to_apic_id(const struct cpumask *cpumask)
22092209
if (first_cpu_of_numa_node >= nr_cpu_ids)
22102210
return -1;
22112211
#ifdef CONFIG_X86_64
2212-
return cpu_data(first_cpu_of_numa_node).apicid;
2212+
return cpu_data(first_cpu_of_numa_node).topo.apicid;
22132213
#else
22142214
return first_cpu_of_numa_node;
22152215
#endif

drivers/virt/acrn/hsm.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -447,7 +447,7 @@ static ssize_t remove_cpu_store(struct device *dev,
447447
if (cpu_online(cpu))
448448
remove_cpu(cpu);
449449

450-
lapicid = cpu_data(cpu).apicid;
450+
lapicid = cpu_data(cpu).topo.apicid;
451451
dev_dbg(dev, "Try to remove cpu %lld with lapicid %lld\n", cpu, lapicid);
452452
ret = hcall_sos_remove_cpu(lapicid);
453453
if (ret < 0) {

0 commit comments

Comments
 (0)