qemu/qapi-qom-Define-cache-enumeration-and-properties-for.patch
Jiabo Feng 74b61da994 QEMU update to version 6.2.0-107:
- 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)
2025-03-26 21:10:58 +08:00

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