From: Zhao Liu <zhao1.liu@linux.intel.com>
To: "Eduardo Habkost" <eduardo@habkost.net>,
"Marcel Apfelbaum" <marcel.apfelbaum@gmail.com>,
"Philippe Mathieu-Daudé" <philmd@linaro.org>,
"Yanan Wang" <wangyanan55@huawei.com>,
"Michael S . Tsirkin" <mst@redhat.com>,
"Richard Henderson" <richard.henderson@linaro.org>,
"Paolo Bonzini" <pbonzini@redhat.com>,
"Marcelo Tosatti" <mtosatti@redhat.com>
Cc: qemu-devel@nongnu.org, kvm@vger.kernel.org,
Zhenyu Wang <zhenyu.z.wang@intel.com>,
Xiaoyao Li <xiaoyao.li@intel.com>,
Babu Moger <babu.moger@amd.com>, Zhao Liu <zhao1.liu@intel.com>,
Zhuocheng Ding <zhuocheng.ding@intel.com>
Subject: [PATCH v4 11/21] i386: Support modules_per_die in X86CPUTopoInfo
Date: Thu, 14 Sep 2023 15:21:49 +0800 [thread overview]
Message-ID: <20230914072159.1177582-12-zhao1.liu@linux.intel.com> (raw)
In-Reply-To: <20230914072159.1177582-1-zhao1.liu@linux.intel.com>
From: Zhuocheng Ding <zhuocheng.ding@intel.com>
Support module level in i386 cpu topology structure "X86CPUTopoInfo".
Since x86 does not yet support the "clusters" parameter in "-smp",
X86CPUTopoInfo.modules_per_die is currently always 1. Therefore, the
module level width in APIC ID, which can be calculated by
"apicid_bitwidth_for_count(topo_info->modules_per_die)", is always 0
for now, so we can directly add APIC ID related helpers to support
module level parsing.
In addition, update topology structure in test-x86-topo.c.
Signed-off-by: Zhuocheng Ding <zhuocheng.ding@intel.com>
Co-developed-by: Zhao Liu <zhao1.liu@intel.com>
Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
---
Changes since v3:
* Drop the description about not exposing module level in commit
message.
* Update topology related calculation in newly added helpers:
num_cpus_by_topo_level() and apicid_offset_by_topo_level().
* Since the code change, drop the "Acked-by" tag.
Changes since v1:
* Include module level related helpers (apicid_module_width() and
apicid_module_offset()) in this patch. (Yanan)
---
hw/i386/x86.c | 3 ++-
include/hw/i386/topology.h | 22 +++++++++++++++----
target/i386/cpu.c | 17 +++++++++-----
tests/unit/test-x86-topo.c | 45 ++++++++++++++++++++------------------
4 files changed, 55 insertions(+), 32 deletions(-)
diff --git a/hw/i386/x86.c b/hw/i386/x86.c
index 9c61b6882b99..267bb0f96ca5 100644
--- a/hw/i386/x86.c
+++ b/hw/i386/x86.c
@@ -72,7 +72,8 @@ static void init_topo_info(X86CPUTopoInfo *topo_info,
MachineState *ms = MACHINE(x86ms);
topo_info->dies_per_pkg = ms->smp.dies;
- topo_info->cores_per_die = ms->smp.cores;
+ topo_info->modules_per_die = ms->smp.clusters;
+ topo_info->cores_per_module = ms->smp.cores;
topo_info->threads_per_core = ms->smp.threads;
}
diff --git a/include/hw/i386/topology.h b/include/hw/i386/topology.h
index 5a19679f618b..c807d3811dd3 100644
--- a/include/hw/i386/topology.h
+++ b/include/hw/i386/topology.h
@@ -56,7 +56,8 @@ typedef struct X86CPUTopoIDs {
typedef struct X86CPUTopoInfo {
unsigned dies_per_pkg;
- unsigned cores_per_die;
+ unsigned modules_per_die;
+ unsigned cores_per_module;
unsigned threads_per_core;
} X86CPUTopoInfo;
@@ -77,7 +78,13 @@ static inline unsigned apicid_smt_width(X86CPUTopoInfo *topo_info)
/* Bit width of the Core_ID field */
static inline unsigned apicid_core_width(X86CPUTopoInfo *topo_info)
{
- return apicid_bitwidth_for_count(topo_info->cores_per_die);
+ return apicid_bitwidth_for_count(topo_info->cores_per_module);
+}
+
+/* Bit width of the Module_ID (cluster ID) field */
+static inline unsigned apicid_module_width(X86CPUTopoInfo *topo_info)
+{
+ return apicid_bitwidth_for_count(topo_info->modules_per_die);
}
/* Bit width of the Die_ID field */
@@ -92,10 +99,16 @@ static inline unsigned apicid_core_offset(X86CPUTopoInfo *topo_info)
return apicid_smt_width(topo_info);
}
+/* Bit offset of the Module_ID (cluster ID) field */
+static inline unsigned apicid_module_offset(X86CPUTopoInfo *topo_info)
+{
+ return apicid_core_offset(topo_info) + apicid_core_width(topo_info);
+}
+
/* Bit offset of the Die_ID field */
static inline unsigned apicid_die_offset(X86CPUTopoInfo *topo_info)
{
- return apicid_core_offset(topo_info) + apicid_core_width(topo_info);
+ return apicid_module_offset(topo_info) + apicid_module_width(topo_info);
}
/* Bit offset of the Pkg_ID (socket ID) field */
@@ -127,7 +140,8 @@ static inline void x86_topo_ids_from_idx(X86CPUTopoInfo *topo_info,
X86CPUTopoIDs *topo_ids)
{
unsigned nr_dies = topo_info->dies_per_pkg;
- unsigned nr_cores = topo_info->cores_per_die;
+ unsigned nr_cores = topo_info->cores_per_module *
+ topo_info->modules_per_die;
unsigned nr_threads = topo_info->threads_per_core;
topo_ids->pkg_id = cpu_index / (nr_dies * nr_cores * nr_threads);
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 401409c5db08..cef9a4606d89 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -277,10 +277,11 @@ static uint32_t num_cpus_by_topo_level(X86CPUTopoInfo *topo_info,
case CPU_TOPO_LEVEL_CORE:
return topo_info->threads_per_core;
case CPU_TOPO_LEVEL_DIE:
- return topo_info->threads_per_core * topo_info->cores_per_die;
+ return topo_info->threads_per_core * topo_info->cores_per_module *
+ topo_info->modules_per_die;
case CPU_TOPO_LEVEL_PACKAGE:
- return topo_info->threads_per_core * topo_info->cores_per_die *
- topo_info->dies_per_pkg;
+ return topo_info->threads_per_core * topo_info->cores_per_module *
+ topo_info->modules_per_die * topo_info->dies_per_pkg;
default:
g_assert_not_reached();
}
@@ -449,7 +450,9 @@ static void encode_cache_cpuid8000001d(CPUCacheInfo *cache,
/* L3 is shared among multiple cores */
if (cache->level == 3) {
- l3_threads = topo_info->cores_per_die * topo_info->threads_per_core;
+ l3_threads = topo_info->modules_per_die *
+ topo_info->cores_per_module *
+ topo_info->threads_per_core;
*eax |= (l3_threads - 1) << 14;
} else {
*eax |= ((topo_info->threads_per_core - 1) << 14);
@@ -6126,10 +6129,12 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
uint32_t cpus_per_pkg;
topo_info.dies_per_pkg = env->nr_dies;
- topo_info.cores_per_die = cs->nr_cores / env->nr_dies;
+ topo_info.modules_per_die = env->nr_modules;
+ topo_info.cores_per_module = cs->nr_cores / env->nr_dies / env->nr_modules;
topo_info.threads_per_core = cs->nr_threads;
- cores_per_pkg = topo_info.cores_per_die * topo_info.dies_per_pkg;
+ cores_per_pkg = topo_info.cores_per_module * topo_info.modules_per_die *
+ topo_info.dies_per_pkg;
cpus_per_pkg = cores_per_pkg * topo_info.threads_per_core;
/* Calculate & apply limits for different index ranges */
diff --git a/tests/unit/test-x86-topo.c b/tests/unit/test-x86-topo.c
index 2b104f86d7c2..f21b8a5d95c2 100644
--- a/tests/unit/test-x86-topo.c
+++ b/tests/unit/test-x86-topo.c
@@ -30,13 +30,16 @@ static void test_topo_bits(void)
{
X86CPUTopoInfo topo_info = {0};
- /* simple tests for 1 thread per core, 1 core per die, 1 die per package */
- topo_info = (X86CPUTopoInfo) {1, 1, 1};
+ /*
+ * simple tests for 1 thread per core, 1 core per module,
+ * 1 module per die, 1 die per package
+ */
+ topo_info = (X86CPUTopoInfo) {1, 1, 1, 1};
g_assert_cmpuint(apicid_smt_width(&topo_info), ==, 0);
g_assert_cmpuint(apicid_core_width(&topo_info), ==, 0);
g_assert_cmpuint(apicid_die_width(&topo_info), ==, 0);
- topo_info = (X86CPUTopoInfo) {1, 1, 1};
+ topo_info = (X86CPUTopoInfo) {1, 1, 1, 1};
g_assert_cmpuint(x86_apicid_from_cpu_idx(&topo_info, 0), ==, 0);
g_assert_cmpuint(x86_apicid_from_cpu_idx(&topo_info, 1), ==, 1);
g_assert_cmpuint(x86_apicid_from_cpu_idx(&topo_info, 2), ==, 2);
@@ -45,39 +48,39 @@ static void test_topo_bits(void)
/* Test field width calculation for multiple values
*/
- topo_info = (X86CPUTopoInfo) {1, 1, 2};
+ topo_info = (X86CPUTopoInfo) {1, 1, 1, 2};
g_assert_cmpuint(apicid_smt_width(&topo_info), ==, 1);
- topo_info = (X86CPUTopoInfo) {1, 1, 3};
+ topo_info = (X86CPUTopoInfo) {1, 1, 1, 3};
g_assert_cmpuint(apicid_smt_width(&topo_info), ==, 2);
- topo_info = (X86CPUTopoInfo) {1, 1, 4};
+ topo_info = (X86CPUTopoInfo) {1, 1, 1, 4};
g_assert_cmpuint(apicid_smt_width(&topo_info), ==, 2);
- topo_info = (X86CPUTopoInfo) {1, 1, 14};
+ topo_info = (X86CPUTopoInfo) {1, 1, 1, 14};
g_assert_cmpuint(apicid_smt_width(&topo_info), ==, 4);
- topo_info = (X86CPUTopoInfo) {1, 1, 15};
+ topo_info = (X86CPUTopoInfo) {1, 1, 1, 15};
g_assert_cmpuint(apicid_smt_width(&topo_info), ==, 4);
- topo_info = (X86CPUTopoInfo) {1, 1, 16};
+ topo_info = (X86CPUTopoInfo) {1, 1, 1, 16};
g_assert_cmpuint(apicid_smt_width(&topo_info), ==, 4);
- topo_info = (X86CPUTopoInfo) {1, 1, 17};
+ topo_info = (X86CPUTopoInfo) {1, 1, 1, 17};
g_assert_cmpuint(apicid_smt_width(&topo_info), ==, 5);
- topo_info = (X86CPUTopoInfo) {1, 30, 2};
+ topo_info = (X86CPUTopoInfo) {1, 1, 30, 2};
g_assert_cmpuint(apicid_core_width(&topo_info), ==, 5);
- topo_info = (X86CPUTopoInfo) {1, 31, 2};
+ topo_info = (X86CPUTopoInfo) {1, 1, 31, 2};
g_assert_cmpuint(apicid_core_width(&topo_info), ==, 5);
- topo_info = (X86CPUTopoInfo) {1, 32, 2};
+ topo_info = (X86CPUTopoInfo) {1, 1, 32, 2};
g_assert_cmpuint(apicid_core_width(&topo_info), ==, 5);
- topo_info = (X86CPUTopoInfo) {1, 33, 2};
+ topo_info = (X86CPUTopoInfo) {1, 1, 33, 2};
g_assert_cmpuint(apicid_core_width(&topo_info), ==, 6);
- topo_info = (X86CPUTopoInfo) {1, 30, 2};
+ topo_info = (X86CPUTopoInfo) {1, 1, 30, 2};
g_assert_cmpuint(apicid_die_width(&topo_info), ==, 0);
- topo_info = (X86CPUTopoInfo) {2, 30, 2};
+ topo_info = (X86CPUTopoInfo) {2, 1, 30, 2};
g_assert_cmpuint(apicid_die_width(&topo_info), ==, 1);
- topo_info = (X86CPUTopoInfo) {3, 30, 2};
+ topo_info = (X86CPUTopoInfo) {3, 1, 30, 2};
g_assert_cmpuint(apicid_die_width(&topo_info), ==, 2);
- topo_info = (X86CPUTopoInfo) {4, 30, 2};
+ topo_info = (X86CPUTopoInfo) {4, 1, 30, 2};
g_assert_cmpuint(apicid_die_width(&topo_info), ==, 2);
/* build a weird topology and see if IDs are calculated correctly
@@ -85,18 +88,18 @@ static void test_topo_bits(void)
/* This will use 2 bits for thread ID and 3 bits for core ID
*/
- topo_info = (X86CPUTopoInfo) {1, 6, 3};
+ topo_info = (X86CPUTopoInfo) {1, 1, 6, 3};
g_assert_cmpuint(apicid_smt_width(&topo_info), ==, 2);
g_assert_cmpuint(apicid_core_offset(&topo_info), ==, 2);
g_assert_cmpuint(apicid_die_offset(&topo_info), ==, 5);
g_assert_cmpuint(apicid_pkg_offset(&topo_info), ==, 5);
- topo_info = (X86CPUTopoInfo) {1, 6, 3};
+ topo_info = (X86CPUTopoInfo) {1, 1, 6, 3};
g_assert_cmpuint(x86_apicid_from_cpu_idx(&topo_info, 0), ==, 0);
g_assert_cmpuint(x86_apicid_from_cpu_idx(&topo_info, 1), ==, 1);
g_assert_cmpuint(x86_apicid_from_cpu_idx(&topo_info, 2), ==, 2);
- topo_info = (X86CPUTopoInfo) {1, 6, 3};
+ topo_info = (X86CPUTopoInfo) {1, 1, 6, 3};
g_assert_cmpuint(x86_apicid_from_cpu_idx(&topo_info, 1 * 3 + 0), ==,
(1 << 2) | 0);
g_assert_cmpuint(x86_apicid_from_cpu_idx(&topo_info, 1 * 3 + 1), ==,
--
2.34.1
next prev parent reply other threads:[~2023-09-14 7:16 UTC|newest]
Thread overview: 43+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-09-14 7:21 [PATCH v4 00/21] Support smp.clusters for x86 in QEMU Zhao Liu
2023-09-14 7:21 ` [PATCH v4 01/21] i386: Fix comment style in topology.h Zhao Liu
2023-09-22 16:05 ` Moger, Babu
2023-09-26 3:11 ` Zhao Liu
2023-09-14 7:21 ` [PATCH v4 02/21] tests: Rename test-x86-cpuid.c to test-x86-topo.c Zhao Liu
2023-09-14 7:21 ` [PATCH v4 03/21] softmmu: Fix CPUSTATE.nr_cores' calculation Zhao Liu
2023-09-14 7:31 ` Philippe Mathieu-Daudé
2023-09-15 7:39 ` Zhao Liu
2023-09-14 7:21 ` [PATCH v4 04/21] hw/cpu: Update the comments of nr_cores and nr_dies Zhao Liu
2023-09-14 7:32 ` Philippe Mathieu-Daudé
2023-09-15 7:40 ` Zhao Liu
2023-09-14 7:21 ` [PATCH v4 05/21] i386/cpu: Fix i/d-cache topology to core level for Intel CPU Zhao Liu
2023-09-14 7:21 ` [PATCH v4 06/21] i386/cpu: Use APIC ID offset to encode cache topo in CPUID[4] Zhao Liu
2023-09-14 7:21 ` [PATCH v4 07/21] i386/cpu: Consolidate the use of topo_info in cpu_x86_cpuid() Zhao Liu
2023-09-14 7:21 ` [PATCH v4 08/21] i386: Split topology types of CPUID[0x1F] from the definitions of CPUID[0xB] Zhao Liu
2023-09-14 7:21 ` [PATCH v4 09/21] i386: Decouple CPUID[0x1F] subleaf with specific topology level Zhao Liu
2023-09-14 7:21 ` [PATCH v4 10/21] i386: Introduce module-level cpu topology to CPUX86State Zhao Liu
2023-09-14 7:38 ` Philippe Mathieu-Daudé
2023-09-15 7:50 ` Zhao Liu
2023-09-14 7:21 ` Zhao Liu [this message]
2023-09-14 7:21 ` [PATCH v4 12/21] i386: Expose module level in CPUID[0x1F] Zhao Liu
2023-09-14 7:21 ` [PATCH v4 13/21] i386: Support module_id in X86CPUTopoIDs Zhao Liu
2023-09-14 7:21 ` [PATCH v4 14/21] i386/cpu: Introduce cluster-id to X86CPU Zhao Liu
2023-09-14 7:21 ` [PATCH v4 15/21] tests: Add test case of APIC ID for module level parsing Zhao Liu
2023-09-14 7:21 ` [PATCH v4 16/21] hw/i386/pc: Support smp.clusters for x86 PC machine Zhao Liu
2023-09-14 7:21 ` [PATCH v4 17/21] i386: Add cache topology info in CPUCacheInfo Zhao Liu
2023-09-14 7:21 ` [PATCH v4 18/21] i386: Use CPUCacheInfo.share_level to encode CPUID[4] Zhao Liu
2023-09-14 7:21 ` [PATCH v4 19/21] i386: Use offsets get NumSharingCache for CPUID[0x8000001D].EAX[bits 25:14] Zhao Liu
2023-09-22 19:27 ` Moger, Babu
2023-09-26 3:10 ` Zhao Liu
2023-09-14 7:21 ` [PATCH v4 20/21] i386: Use CPUCacheInfo.share_level to encode " Zhao Liu
2023-09-22 19:27 ` Moger, Babu
2023-09-26 3:08 ` Zhao Liu
2023-09-14 7:21 ` [PATCH v4 21/21] i386: Add new property to control L2 cache topo in CPUID.04H Zhao Liu
2023-09-14 7:41 ` Philippe Mathieu-Daudé
2023-09-15 7:53 ` Zhao Liu
2023-10-03 12:57 ` Michael S. Tsirkin
2023-10-06 16:36 ` Zhao Liu
2023-10-18 14:12 ` Zhao Liu
2023-09-22 16:03 ` [PATCH v4 00/21] Support smp.clusters for x86 in QEMU Moger, Babu
2023-09-26 3:11 ` Zhao Liu
2023-10-18 12:06 ` Michael S. Tsirkin
2023-10-18 14:08 ` Zhao Liu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230914072159.1177582-12-zhao1.liu@linux.intel.com \
--to=zhao1.liu@linux.intel.com \
--cc=babu.moger@amd.com \
--cc=eduardo@habkost.net \
--cc=kvm@vger.kernel.org \
--cc=marcel.apfelbaum@gmail.com \
--cc=mst@redhat.com \
--cc=mtosatti@redhat.com \
--cc=pbonzini@redhat.com \
--cc=philmd@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=richard.henderson@linaro.org \
--cc=wangyanan55@huawei.com \
--cc=xiaoyao.li@intel.com \
--cc=zhao1.liu@intel.com \
--cc=zhenyu.z.wang@intel.com \
--cc=zhuocheng.ding@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).