Skip to content

Commit 84b71a1

Browse files
calmisibonzini
authored andcommitted
i386/cpu: Track a X86CPUTopoInfo directly in CPUX86State
The name of nr_modules/nr_dies are ambiguous and they mislead people. The purpose of them is to record and form the topology information. So just maintain a X86CPUTopoInfo member in CPUX86State instead. Then nr_modules and nr_dies can be dropped. As the benefit, x86 can switch to use information in CPUX86State::topo_info and get rid of the nr_cores and nr_threads in CPUState. This helps remove the dependency on qemu_init_vcpu(), so that x86 can get and use topology info earlier in x86_cpu_realizefn(); drop the comment that highlighted the depedency. Signed-off-by: Xiaoyao Li <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Paolo Bonzini <[email protected]>
1 parent e60cbee commit 84b71a1

File tree

4 files changed

+30
-45
lines changed

4 files changed

+30
-45
lines changed

hw/i386/x86-common.c

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ void x86_cpu_pre_plug(HotplugHandler *hotplug_dev,
248248
CPUX86State *env = &cpu->env;
249249
MachineState *ms = MACHINE(hotplug_dev);
250250
X86MachineState *x86ms = X86_MACHINE(hotplug_dev);
251-
X86CPUTopoInfo topo_info;
251+
X86CPUTopoInfo *topo_info = &env->topo_info;
252252

253253
if (!object_dynamic_cast(OBJECT(cpu), ms->cpu_type)) {
254254
error_setg(errp, "Invalid CPU type, expected cpu type: '%s'",
@@ -267,15 +267,13 @@ void x86_cpu_pre_plug(HotplugHandler *hotplug_dev,
267267
}
268268
}
269269

270-
init_topo_info(&topo_info, x86ms);
270+
init_topo_info(topo_info, x86ms);
271271

272272
if (ms->smp.modules > 1) {
273-
env->nr_modules = ms->smp.modules;
274273
set_bit(CPU_TOPOLOGY_LEVEL_MODULE, env->avail_cpu_topo);
275274
}
276275

277276
if (ms->smp.dies > 1) {
278-
env->nr_dies = ms->smp.dies;
279277
set_bit(CPU_TOPOLOGY_LEVEL_DIE, env->avail_cpu_topo);
280278
}
281279

@@ -346,12 +344,12 @@ void x86_cpu_pre_plug(HotplugHandler *hotplug_dev,
346344
topo_ids.module_id = cpu->module_id;
347345
topo_ids.core_id = cpu->core_id;
348346
topo_ids.smt_id = cpu->thread_id;
349-
cpu->apic_id = x86_apicid_from_topo_ids(&topo_info, &topo_ids);
347+
cpu->apic_id = x86_apicid_from_topo_ids(topo_info, &topo_ids);
350348
}
351349

352350
cpu_slot = x86_find_cpu_slot(MACHINE(x86ms), cpu->apic_id, &idx);
353351
if (!cpu_slot) {
354-
x86_topo_ids_from_apicid(cpu->apic_id, &topo_info, &topo_ids);
352+
x86_topo_ids_from_apicid(cpu->apic_id, topo_info, &topo_ids);
355353

356354
error_setg(errp,
357355
"Invalid CPU [socket: %u, die: %u, module: %u, core: %u, thread: %u]"
@@ -374,7 +372,7 @@ void x86_cpu_pre_plug(HotplugHandler *hotplug_dev,
374372
/* TODO: move socket_id/core_id/thread_id checks into x86_cpu_realizefn()
375373
* once -smp refactoring is complete and there will be CPU private
376374
* CPUState::nr_cores and CPUState::nr_threads fields instead of globals */
377-
x86_topo_ids_from_apicid(cpu->apic_id, &topo_info, &topo_ids);
375+
x86_topo_ids_from_apicid(cpu->apic_id, topo_info, &topo_ids);
378376
if (cpu->socket_id != -1 && cpu->socket_id != topo_ids.pkg_id) {
379377
error_setg(errp, "property socket-id: %u doesn't match set apic-id:"
380378
" 0x%x (socket-id: %u)", cpu->socket_id, cpu->apic_id,

target/i386/cpu-system.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -312,11 +312,11 @@ void x86_cpu_get_crash_info_qom(Object *obj, Visitor *v,
312312

313313
uint64_t cpu_x86_get_msr_core_thread_count(X86CPU *cpu)
314314
{
315-
CPUState *cs = CPU(cpu);
315+
CPUX86State *env = &cpu->env;
316316
uint64_t val;
317317

318-
val = cs->nr_threads * cs->nr_cores; /* thread count, bits 15..0 */
319-
val |= ((uint32_t)cs->nr_cores << 16); /* core count, bits 31..16 */
318+
val = x86_threads_per_pkg(&env->topo_info); /* thread count, bits 15..0 */
319+
val |= x86_cores_per_pkg(&env->topo_info) << 16; /* core count, bits 31..16 */
320320

321321
return val;
322322
}

target/i386/cpu.c

Lines changed: 21 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -6496,15 +6496,10 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
64966496
CPUState *cs = env_cpu(env);
64976497
uint32_t limit;
64986498
uint32_t signature[3];
6499-
X86CPUTopoInfo topo_info;
6499+
X86CPUTopoInfo *topo_info = &env->topo_info;
65006500
uint32_t threads_per_pkg;
65016501

6502-
topo_info.dies_per_pkg = env->nr_dies;
6503-
topo_info.modules_per_die = env->nr_modules;
6504-
topo_info.cores_per_module = cs->nr_cores / env->nr_dies / env->nr_modules;
6505-
topo_info.threads_per_core = cs->nr_threads;
6506-
6507-
threads_per_pkg = x86_threads_per_pkg(&topo_info);
6502+
threads_per_pkg = x86_threads_per_pkg(topo_info);
65086503

65096504
/* Calculate & apply limits for different index ranges */
65106505
if (index >= 0xC0000000) {
@@ -6581,12 +6576,12 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
65816576
int host_vcpus_per_cache = 1 + ((*eax & 0x3FFC000) >> 14);
65826577

65836578
*eax &= ~0xFC000000;
6584-
*eax |= max_core_ids_in_package(&topo_info) << 26;
6579+
*eax |= max_core_ids_in_package(topo_info) << 26;
65856580
if (host_vcpus_per_cache > threads_per_pkg) {
65866581
*eax &= ~0x3FFC000;
65876582

65886583
/* Share the cache at package level. */
6589-
*eax |= max_thread_ids_for_cache(&topo_info,
6584+
*eax |= max_thread_ids_for_cache(topo_info,
65906585
CPU_TOPOLOGY_LEVEL_SOCKET) << 14;
65916586
}
65926587
}
@@ -6598,29 +6593,29 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
65986593
switch (count) {
65996594
case 0: /* L1 dcache info */
66006595
encode_cache_cpuid4(env->cache_info_cpuid4.l1d_cache,
6601-
&topo_info,
6596+
topo_info,
66026597
eax, ebx, ecx, edx);
66036598
if (!cpu->l1_cache_per_core) {
66046599
*eax &= ~MAKE_64BIT_MASK(14, 12);
66056600
}
66066601
break;
66076602
case 1: /* L1 icache info */
66086603
encode_cache_cpuid4(env->cache_info_cpuid4.l1i_cache,
6609-
&topo_info,
6604+
topo_info,
66106605
eax, ebx, ecx, edx);
66116606
if (!cpu->l1_cache_per_core) {
66126607
*eax &= ~MAKE_64BIT_MASK(14, 12);
66136608
}
66146609
break;
66156610
case 2: /* L2 cache info */
66166611
encode_cache_cpuid4(env->cache_info_cpuid4.l2_cache,
6617-
&topo_info,
6612+
topo_info,
66186613
eax, ebx, ecx, edx);
66196614
break;
66206615
case 3: /* L3 cache info */
66216616
if (cpu->enable_l3_cache) {
66226617
encode_cache_cpuid4(env->cache_info_cpuid4.l3_cache,
6623-
&topo_info,
6618+
topo_info,
66246619
eax, ebx, ecx, edx);
66256620
break;
66266621
}
@@ -6703,12 +6698,12 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
67036698

67046699
switch (count) {
67056700
case 0:
6706-
*eax = apicid_core_offset(&topo_info);
6707-
*ebx = topo_info.threads_per_core;
6701+
*eax = apicid_core_offset(topo_info);
6702+
*ebx = topo_info->threads_per_core;
67086703
*ecx |= CPUID_B_ECX_TOPO_LEVEL_SMT << 8;
67096704
break;
67106705
case 1:
6711-
*eax = apicid_pkg_offset(&topo_info);
6706+
*eax = apicid_pkg_offset(topo_info);
67126707
*ebx = threads_per_pkg;
67136708
*ecx |= CPUID_B_ECX_TOPO_LEVEL_CORE << 8;
67146709
break;
@@ -6734,7 +6729,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
67346729
break;
67356730
}
67366731

6737-
encode_topo_cpuid1f(env, count, &topo_info, eax, ebx, ecx, edx);
6732+
encode_topo_cpuid1f(env, count, topo_info, eax, ebx, ecx, edx);
67386733
break;
67396734
case 0xD: {
67406735
/* Processor Extended State */
@@ -7037,7 +7032,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
70377032
* thread ID within a package".
70387033
* Bits 7:0 is "The number of threads in the package is NC+1"
70397034
*/
7040-
*ecx = (apicid_pkg_offset(&topo_info) << 12) |
7035+
*ecx = (apicid_pkg_offset(topo_info) << 12) |
70417036
(threads_per_pkg - 1);
70427037
} else {
70437038
*ecx = 0;
@@ -7066,19 +7061,19 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
70667061
switch (count) {
70677062
case 0: /* L1 dcache info */
70687063
encode_cache_cpuid8000001d(env->cache_info_amd.l1d_cache,
7069-
&topo_info, eax, ebx, ecx, edx);
7064+
topo_info, eax, ebx, ecx, edx);
70707065
break;
70717066
case 1: /* L1 icache info */
70727067
encode_cache_cpuid8000001d(env->cache_info_amd.l1i_cache,
7073-
&topo_info, eax, ebx, ecx, edx);
7068+
topo_info, eax, ebx, ecx, edx);
70747069
break;
70757070
case 2: /* L2 cache info */
70767071
encode_cache_cpuid8000001d(env->cache_info_amd.l2_cache,
7077-
&topo_info, eax, ebx, ecx, edx);
7072+
topo_info, eax, ebx, ecx, edx);
70787073
break;
70797074
case 3: /* L3 cache info */
70807075
encode_cache_cpuid8000001d(env->cache_info_amd.l3_cache,
7081-
&topo_info, eax, ebx, ecx, edx);
7076+
topo_info, eax, ebx, ecx, edx);
70827077
break;
70837078
default: /* end of info */
70847079
*eax = *ebx = *ecx = *edx = 0;
@@ -7090,7 +7085,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
70907085
break;
70917086
case 0x8000001E:
70927087
if (cpu->core_id <= 255) {
7093-
encode_topo_cpuid8000001e(cpu, &topo_info, eax, ebx, ecx, edx);
7088+
encode_topo_cpuid8000001e(cpu, topo_info, eax, ebx, ecx, edx);
70947089
} else {
70957090
*eax = 0;
70967091
*ebx = 0;
@@ -7997,17 +7992,14 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
79977992
* fixes this issue by adjusting CPUID_0000_0001_EBX and CPUID_8000_0008_ECX
79987993
* based on inputs (sockets,cores,threads), it is still better to give
79997994
* users a warning.
8000-
*
8001-
* NOTE: the following code has to follow qemu_init_vcpu(). Otherwise
8002-
* cs->nr_threads hasn't be populated yet and the checking is incorrect.
80037995
*/
80047996
if (IS_AMD_CPU(env) &&
80057997
!(env->features[FEAT_8000_0001_ECX] & CPUID_EXT3_TOPOEXT) &&
8006-
cs->nr_threads > 1) {
7998+
env->topo_info.threads_per_core > 1) {
80077999
warn_report_once("This family of AMD CPU doesn't support "
80088000
"hyperthreading(%d). Please configure -smp "
80098001
"options properly or try enabling topoext "
8010-
"feature.", cs->nr_threads);
8002+
"feature.", env->topo_info.threads_per_core);
80118003
}
80128004

80138005
#ifndef CONFIG_USER_ONLY
@@ -8168,8 +8160,7 @@ static void x86_cpu_init_default_topo(X86CPU *cpu)
81688160
{
81698161
CPUX86State *env = &cpu->env;
81708162

8171-
env->nr_modules = 1;
8172-
env->nr_dies = 1;
8163+
env->topo_info = (X86CPUTopoInfo) {1, 1, 1, 1};
81738164

81748165
/* thread, core and socket levels are set by default. */
81758166
set_bit(CPU_TOPOLOGY_LEVEL_THREAD, env->avail_cpu_topo);

target/i386/cpu.h

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2068,11 +2068,7 @@ typedef struct CPUArchState {
20682068

20692069
TPRAccess tpr_access_type;
20702070

2071-
/* Number of dies within this CPU package. */
2072-
unsigned nr_dies;
2073-
2074-
/* Number of modules within one die. */
2075-
unsigned nr_modules;
2071+
X86CPUTopoInfo topo_info;
20762072

20772073
/* Bitmap of available CPU topology levels for this CPU. */
20782074
DECLARE_BITMAP(avail_cpu_topo, CPU_TOPOLOGY_LEVEL__MAX);

0 commit comments

Comments
 (0)