- qemu: Support specifying the cache size presented to guest - hw/core/machine-smp: Initialize caches_bitmap before reading - qapi/qom: Define cache enumeration and properties for machine - linux-aio: fix unbalanced plugged counter in laio_io_unplug() Signed-off-by: Jiabo Feng <fengjiabo1@huawei.com> (cherry picked from commit 5453be865c307703cc43847588fa63ef74ac1ae0)
271 lines
9.0 KiB
Diff
271 lines
9.0 KiB
Diff
From 04d1ae325a2a77025558d833840a62bd08136c44 Mon Sep 17 00:00:00 2001
|
|
From: huangchengfei <huangchengfei3@huawei.com>
|
|
Date: Fri, 7 Mar 2025 15:25:12 +0800
|
|
Subject: [PATCH] qapi/qom: Define cache enumeration and properties for machine
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
mainline inclusion
|
|
from mainline-master
|
|
commit 4e88e7e3403df23a0fd7a95daad1f00da80bcf81
|
|
category: feature
|
|
Reference: https://github.com/qemu/qemu/commit/4e88e7e3403df23a0fd7a95daad1f00da80bcf81
|
|
|
|
commit 4e88e7e3403df23a0fd7a95daad1f00da80bcf81 upstream
|
|
|
|
The x86 and ARM need to allow user to configure cache properties
|
|
(current only topology):
|
|
* For x86, the default cache topology model (of max/host CPU) does not
|
|
always match the Host's real physical cache topology. Performance can
|
|
increase when the configured virtual topology is closer to the
|
|
physical topology than a default topology would be.
|
|
* For ARM, QEMU can't get the cache topology information from the CPU
|
|
registers, then user configuration is necessary. Additionally, the
|
|
cache information is also needed for MPAM emulation (for TCG) to
|
|
build the right PPTT.
|
|
|
|
Define smp-cache related enumeration and properties in QAPI, so that
|
|
user could configure cache properties for SMP system through -machine in
|
|
the subsequent patch.
|
|
|
|
Cache enumeration (CacheLevelAndType) is implemented as the combination
|
|
of cache level (level 1/2/3) and cache type (data/instruction/unified).
|
|
|
|
Currently, separated L1 cache (L1 data cache and L1 instruction cache)
|
|
with unified higher-level cache (e.g., unified L2 and L3 caches), is the
|
|
most common cache architectures.
|
|
|
|
Therefore, enumerate the L1 D-cache, L1 I-cache, L2 cache and L3 cache
|
|
with smp-cache object to add the basic cache topology support. Other
|
|
kinds of caches (e.g., L1 unified or L2/L3 separated caches) can be
|
|
added directly into CacheLevelAndType if necessary.
|
|
|
|
Cache properties (SmpCacheProperties) currently only contains cache
|
|
topology information, and other cache properties can be added in it
|
|
if necessary.
|
|
|
|
Note, define cache topology based on CPU topology level with two
|
|
reasons:
|
|
|
|
1. In practice, a cache will always be bound to the CPU container
|
|
(either private in the CPU container or shared among multiple
|
|
containers), and CPU container is often expressed in terms of CPU
|
|
topology level.
|
|
2. The x86's cache-related CPUIDs encode cache topology based on APIC
|
|
ID's CPU topology layout. And the ACPI PPTT table that ARM/RISCV
|
|
relies on also requires CPU containers to help indicate the private
|
|
shared hierarchy of the cache. Therefore, for SMP systems, it is
|
|
natural to use the CPU topology hierarchy directly in QEMU to define
|
|
the cache topology.
|
|
|
|
With smp-cache QAPI support, add smp cache topology for machine by
|
|
parsing the smp-cache object list.
|
|
|
|
Also add the helper to access/update cache topology level of machine.
|
|
|
|
Round to openeuler:
|
|
*cache topology property is removed
|
|
|
|
Suggested-by: Daniel P. Berrange <berrange@redhat.com>
|
|
Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
|
|
Tested-by: Yongwei Ma <yongwei.ma@intel.com>
|
|
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
|
|
Message-ID: <20241101083331.340178-4-zhao1.liu@intel.com>
|
|
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
|
|
Signed-off-by: huangchengfei <huangchengfei3@huawei.com>
|
|
---
|
|
hw/core/machine-smp.c | 23 ++++++++++++++++++++++
|
|
hw/core/machine.c | 42 +++++++++++++++++++++++++++++++++++++++++
|
|
include/hw/boards.h | 8 ++++++++
|
|
qapi/machine.json | 44 +++++++++++++++++++++++++++++++++++++++++++
|
|
4 files changed, 117 insertions(+)
|
|
|
|
diff --git a/hw/core/machine-smp.c b/hw/core/machine-smp.c
|
|
index b39ed21e65..9d1aa3afb3 100644
|
|
--- a/hw/core/machine-smp.c
|
|
+++ b/hw/core/machine-smp.c
|
|
@@ -193,3 +193,26 @@ void machine_parse_smp_config(MachineState *ms,
|
|
return;
|
|
}
|
|
}
|
|
+
|
|
+bool machine_parse_smp_cache(MachineState *ms,
|
|
+ const SmpCachePropertiesList *caches,
|
|
+ Error **errp)
|
|
+{
|
|
+ const SmpCachePropertiesList *node;
|
|
+ DECLARE_BITMAP(caches_bitmap, CACHE_LEVEL_AND_TYPE__MAX);
|
|
+
|
|
+ for (node = caches; node; node = node->next) {
|
|
+ /* Prohibit users from repeating settings. */
|
|
+ if (test_bit(node->value->cache, caches_bitmap)) {
|
|
+ error_setg(errp,
|
|
+ "Invalid cache properties: %s. "
|
|
+ "The cache properties are duplicated",
|
|
+ CacheLevelAndType_str(node->value->cache));
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ set_bit(node->value->cache, caches_bitmap);
|
|
+ }
|
|
+
|
|
+ return true;
|
|
+}
|
|
\ No newline at end of file
|
|
diff --git a/hw/core/machine.c b/hw/core/machine.c
|
|
index cb539104a1..4cdd9a7300 100644
|
|
--- a/hw/core/machine.c
|
|
+++ b/hw/core/machine.c
|
|
@@ -777,6 +777,39 @@ static void machine_set_smp(Object *obj, Visitor *v, const char *name,
|
|
machine_parse_smp_config(ms, config, errp);
|
|
}
|
|
|
|
+static void machine_get_smp_cache(Object *obj, Visitor *v, const char *name,
|
|
+ void *opaque, Error **errp)
|
|
+{
|
|
+ MachineState *ms = MACHINE(obj);
|
|
+ SmpCache *cache = &ms->smp_cache;
|
|
+ SmpCachePropertiesList *head = NULL;
|
|
+ SmpCachePropertiesList **tail = &head;
|
|
+
|
|
+ for (int i = 0; i < CACHE_LEVEL_AND_TYPE__MAX; i++) {
|
|
+ SmpCacheProperties *node = g_new(SmpCacheProperties, 1);
|
|
+
|
|
+ node->cache = cache->props[i].cache;
|
|
+ QAPI_LIST_APPEND(tail, node);
|
|
+ }
|
|
+
|
|
+ visit_type_SmpCachePropertiesList(v, name, &head, errp);
|
|
+ qapi_free_SmpCachePropertiesList(head);
|
|
+}
|
|
+
|
|
+static void machine_set_smp_cache(Object *obj, Visitor *v, const char *name,
|
|
+ void *opaque, Error **errp)
|
|
+{
|
|
+ MachineState *ms = MACHINE(obj);
|
|
+ SmpCachePropertiesList *caches;
|
|
+
|
|
+ if (!visit_type_SmpCachePropertiesList(v, name, &caches, errp)) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ machine_parse_smp_cache(ms, caches, errp);
|
|
+ qapi_free_SmpCachePropertiesList(caches);
|
|
+}
|
|
+
|
|
static void machine_class_init(ObjectClass *oc, void *data)
|
|
{
|
|
MachineClass *mc = MACHINE_CLASS(oc);
|
|
@@ -821,6 +854,11 @@ static void machine_class_init(ObjectClass *oc, void *data)
|
|
object_class_property_set_description(oc, "smp",
|
|
"CPU topology");
|
|
|
|
+ object_class_property_add(oc, "smp-cache", "SmpCachePropertiesWrapper",
|
|
+ machine_get_smp_cache, machine_set_smp_cache, NULL, NULL);
|
|
+ object_class_property_set_description(oc, "smp-cache",
|
|
+ "Cache properties list for SMP machine");
|
|
+
|
|
object_class_property_add(oc, "phandle-start", "int",
|
|
machine_get_phandle_start, machine_set_phandle_start,
|
|
NULL, NULL);
|
|
@@ -948,6 +986,10 @@ static void machine_initfn(Object *obj)
|
|
ms->smp.clusters = 1;
|
|
ms->smp.cores = 1;
|
|
ms->smp.threads = 1;
|
|
+
|
|
+ for (int i = 0; i < CACHE_LEVEL_AND_TYPE__MAX; i++) {
|
|
+ ms->smp_cache.props[i].cache = (CacheLevelAndType)i;
|
|
+ }
|
|
}
|
|
|
|
static void machine_finalize(Object *obj)
|
|
diff --git a/include/hw/boards.h b/include/hw/boards.h
|
|
index f49a2578ea..59f04caf3f 100644
|
|
--- a/include/hw/boards.h
|
|
+++ b/include/hw/boards.h
|
|
@@ -36,6 +36,9 @@ void machine_set_cpu_numa_node(MachineState *machine,
|
|
Error **errp);
|
|
void machine_parse_smp_config(MachineState *ms,
|
|
const SMPConfiguration *config, Error **errp);
|
|
+bool machine_parse_smp_cache(MachineState *ms,
|
|
+ const SmpCachePropertiesList *caches,
|
|
+ Error **errp);
|
|
|
|
/**
|
|
* machine_class_allow_dynamic_sysbus_dev: Add type to list of valid devices
|
|
@@ -316,6 +319,10 @@ typedef struct CpuTopology {
|
|
unsigned int max_cpus;
|
|
} CpuTopology;
|
|
|
|
+typedef struct SmpCache {
|
|
+ SmpCacheProperties props[CACHE_LEVEL_AND_TYPE__MAX];
|
|
+} SmpCache;
|
|
+
|
|
/**
|
|
* MachineState:
|
|
*/
|
|
@@ -359,6 +366,7 @@ struct MachineState {
|
|
AccelState *accelerator;
|
|
CPUArchIdList *possible_cpus;
|
|
CpuTopology smp;
|
|
+ SmpCache smp_cache;
|
|
struct NVDIMMState *nvdimms_state;
|
|
struct NumaState *numa_state;
|
|
};
|
|
diff --git a/qapi/machine.json b/qapi/machine.json
|
|
index 31b0350b99..676e16477b 100644
|
|
--- a/qapi/machine.json
|
|
+++ b/qapi/machine.json
|
|
@@ -1570,3 +1570,47 @@
|
|
{ 'command': 'x-query-usb',
|
|
'returns': 'HumanReadableText',
|
|
'features': [ 'unstable' ] }
|
|
+
|
|
+##
|
|
+# @CacheLevelAndType:
|
|
+#
|
|
+# Caches a system may have. The enumeration value here is the
|
|
+# combination of cache level and cache type.
|
|
+#
|
|
+# @l1d: L1 data cache.
|
|
+#
|
|
+# @l1i: L1 instruction cache.
|
|
+#
|
|
+# @l2: L2 (unified) cache.
|
|
+#
|
|
+# @l3: L3 (unified) cache
|
|
+#
|
|
+# Since: 9.2
|
|
+##
|
|
+{ 'enum': 'CacheLevelAndType',
|
|
+ 'data': [ 'l1d', 'l1i', 'l2', 'l3' ] }
|
|
+
|
|
+##
|
|
+# @SmpCacheProperties:
|
|
+#
|
|
+# Cache information for SMP system.
|
|
+#
|
|
+# @cache: Cache name, which is the combination of cache level and cache type.
|
|
+#
|
|
+# Since: 9.2
|
|
+##
|
|
+{ 'struct': 'SmpCacheProperties',
|
|
+ 'data': {
|
|
+ 'cache': 'CacheLevelAndType' } }
|
|
+
|
|
+##
|
|
+# @SmpCachePropertiesWrapper:
|
|
+#
|
|
+# List wrapper of SmpCacheProperties.
|
|
+#
|
|
+# @caches: the list of SmpCacheProperties.
|
|
+#
|
|
+# Since 9.2
|
|
+##
|
|
+{ 'struct': 'SmpCachePropertiesWrapper',
|
|
+ 'data': { 'caches': ['SmpCacheProperties'] } }
|
|
--
|
|
2.41.0.windows.1
|
|
|