[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[RFC 6/7] Add qmp interfaces to add/release dynamic capacity extents
|
From: |
Fan Ni |
|
Subject: |
[RFC 6/7] Add qmp interfaces to add/release dynamic capacity extents |
|
Date: |
Thu, 11 May 2023 17:56:40 +0000 |
From: Fan Ni <nifan@outlook.com>
Since fabric manager emulation is not supported yet, the change implements
the functions to add/release dynamic capacity extents as QMP interfaces.
1. Add dynamic capacity extents:
For example, the command to add two continuous extents (each is 128MB
long) to region 0 (starting at dpa offset 0) looks like below:
{ "execute": "qmp_capabilities" }
{ "execute": "cxl-add-dynamic-capacity-event",
"arguments": {
"path": "/machine/peripheral/cxl-pmem0",
"region-id" : 0,
"num-extent": 2,
"dpa":0,
"extent-len": 128
}
}
2. Release dynamic capacity extents:
For example, the command to release an extent of size 128MB from region
0 (starting at dpa offset 0) look like below:
{ "execute": "cxl-release-dynamic-capacity-event",
"arguments": {
"path": "/machine/peripheral/cxl-pmem0",
"region-id" : 0,
"num-extent": 1 ,
"dpa":0,
"extent-len": 128
}
}
Signed-off-by: Fan Ni <fan.ni@samsung.com>
---
hw/mem/cxl_type3.c | 127 ++++++++++++++++++++++++++++++++++++
include/hw/cxl/cxl_events.h | 16 +++++
qapi/cxl.json | 44 +++++++++++++
3 files changed, 187 insertions(+)
diff --git a/hw/mem/cxl_type3.c b/hw/mem/cxl_type3.c
index 23954711b5..70d47d43b9 100644
--- a/hw/mem/cxl_type3.c
+++ b/hw/mem/cxl_type3.c
@@ -1651,6 +1651,133 @@ void qmp_cxl_inject_memory_module_event(const char
*path, CxlEventLog log,
}
}
+static const QemuUUID dynamic_capacity_uuid = {
+ .data = UUID(0xca95afa7, 0xf183, 0x4018, 0x8c, 0x2f,
+ 0x95, 0x26, 0x8e, 0x10, 0x1a, 0x2a),
+};
+
+static void qmp_cxl_process_dynamic_capacity_event(const char *path,
CxlEventLog log,
+ uint8_t flags, uint8_t type, uint16_t hid, uint8_t rid,
uint32_t extent_cnt,
+ CXLDCExtent_raw *extents, Error **errp)
+{
+ Object *obj = object_resolve_path(path, NULL);
+ CXLEventDynamicCapacity dCap;
+ CXLEventRecordHdr *hdr = &dCap.hdr;
+ CXLDeviceState *cxlds;
+ CXLType3Dev *dcd;
+ int i;
+
+ if (!obj) {
+ error_setg(errp, "Unable to resolve path");
+ return;
+ }
+ if (!object_dynamic_cast(obj, TYPE_CXL_TYPE3)) {
+ error_setg(errp, "Path not point to a valid CXL type3 device");
+ return;
+ }
+
+ dcd = CXL_TYPE3(obj);
+ cxlds = &dcd->cxl_dstate;
+ memset(&dCap, 0, sizeof(dCap));
+
+ if (!dcd->dc.num_regions) {
+ error_setg(errp, "No dynamic capacity support from the device");
+ return;
+ }
+
+ /*
+ * 8.2.9.1.5
+ * All Dynamic Capacity event records shall set the Event Record
+ * Severity field in the Common Event Record Format to Informational
+ * Event. All Dynamic Capacity related events shall be logged in the
+ * Dynamic Capacity Event Log.
+ */
+ assert(flags & (1<<CXL_EVENT_TYPE_INFO));
+ cxl_assign_event_header(hdr, &dynamic_capacity_uuid, flags,
sizeof(dCap));
+
+ /*
+ * 00h: add capacity
+ * 01h: release capacity
+ * 02h: forced capacity release
+ * 03h: region configuration updated
+ * 04h: Add capacity response
+ * 05h: capacity released
+ **/
+ dCap.type = type;
+ stw_le_p(&dCap.host_id, hid);
+ dCap.updated_region_id = rid;
+ for (i = 0; i < extent_cnt; i++) {
+ extents[i].start_dpa += dcd->dc.regions[rid].base;
+ memcpy(&dCap.dynamic_capacity_extent, &extents[i]
+ , sizeof(CXLDCExtent_raw));
+
+ if (cxl_event_insert(cxlds, CXL_EVENT_TYPE_DYNAMIC_CAP,
+ (CXLEventRecordRaw *)&dCap)) {
+ ;
+ }
+ cxl_event_irq_assert(dcd);
+ }
+}
+
+#define MEM_BLK_SIZE_MB 128
+void qmp_cxl_add_dynamic_capacity_event(const char *path, uint8_t region_id,
+ uint32_t num_exent, uint64_t dpa, uint64_t extent_len_MB, Error
**errp)
+{
+ uint8_t flags = 1 << CXL_EVENT_TYPE_INFO;
+ CXLDCExtent_raw *extents;
+ int i;
+
+ if (extent_len_MB < MEM_BLK_SIZE_MB) {
+ error_setg(errp,
+ "extent size cannot be smaller than memory block size
(%dMB)",
+ MEM_BLK_SIZE_MB);
+ return;
+ }
+
+ extents = g_new0(CXLDCExtent_raw, num_exent);
+ for (i = 0; i < num_exent; i++) {
+ extents[i].start_dpa = dpa;
+ extents[i].len = extent_len_MB*1024*1024;
+ memset(extents[i].tag, 0, 0x10);
+ extents[i].shared_seq = 0;
+ dpa += extents[i].len;
+ }
+
+ qmp_cxl_process_dynamic_capacity_event(path,
CXL_EVENT_LOG_INFORMATIONAL,
+ flags, 0x0, 0, region_id, num_exent, extents, errp);
+
+ g_free(extents);
+}
+
+void qmp_cxl_release_dynamic_capacity_event(const char *path, uint8_t
region_id,
+ uint32_t num_exent, uint64_t dpa, uint64_t extent_len_MB, Error
**errp)
+{
+ uint8_t flags = 1 << CXL_EVENT_TYPE_INFO;
+ CXLDCExtent_raw *extents;
+ int i;
+
+ if (extent_len_MB < MEM_BLK_SIZE_MB) {
+ error_setg(errp,
+ "extent size cannot be smaller than memory block size
(%dMB)",
+ MEM_BLK_SIZE_MB);
+ return;
+ }
+
+ extents = g_new0(CXLDCExtent_raw, num_exent);
+ for (i = 0; i < num_exent; i++) {
+ extents[i].start_dpa = dpa;
+ extents[i].len = extent_len_MB*1024*1024;
+ memset(extents[i].tag, 0, 0x10);
+ extents[i].shared_seq = 0;
+ dpa += extents[i].len;
+ }
+
+ qmp_cxl_process_dynamic_capacity_event(path,
CXL_EVENT_LOG_INFORMATIONAL,
+ flags, 0x1, 0, region_id, num_exent, extents, errp);
+
+ g_free(extents);
+}
+
static void ct3_class_init(ObjectClass *oc, void *data)
{
DeviceClass *dc = DEVICE_CLASS(oc);
diff --git a/include/hw/cxl/cxl_events.h b/include/hw/cxl/cxl_events.h
index 089ba2091f..dd00458d1d 100644
--- a/include/hw/cxl/cxl_events.h
+++ b/include/hw/cxl/cxl_events.h
@@ -165,4 +165,20 @@ typedef struct CXLEventMemoryModule {
uint8_t reserved[0x3d];
} QEMU_PACKED CXLEventMemoryModule;
+/*
+ * Dynamic Capacity Event Record
+ * CXL Rev 3.0 Section 8.2.9.2.1.5: Table 8-47
+ * All fields little endian.
+ */
+typedef struct CXLEventDynamicCapacity {
+ CXLEventRecordHdr hdr;
+ uint8_t type;
+ uint8_t reserved1;
+ uint16_t host_id;
+ uint8_t updated_region_id;
+ uint8_t reserved2[3];
+ uint8_t dynamic_capacity_extent[0x28]; /* defined in cxl_device.h */
+ uint8_t reserved[0x20];
+} QEMU_PACKED CXLEventDynamicCapacity;
+
#endif /* CXL_EVENTS_H */
diff --git a/qapi/cxl.json b/qapi/cxl.json
index 8b3d30cd71..c9a9a45ce4 100644
--- a/qapi/cxl.json
+++ b/qapi/cxl.json
@@ -264,3 +264,47 @@
'type': 'CxlCorErrorType'
}
}
+
+##
+# @cxl-add-dynamic-capacity-event:
+#
+# Command to add dynamic capacity extent event
+#
+# @path: CXL DCD canonical QOM path
+# @region-id: region id
+# @num-extent: number of extents to add, test only
+# @dpa: start dpa for the operation
+# @extent-len: extent size in MB
+#
+# Since: 8.0
+##
+{ 'command': 'cxl-add-dynamic-capacity-event',
+ 'data': { 'path': 'str',
+ 'region-id': 'uint8',
+ 'num-extent': 'uint32',
+ 'dpa':'uint64',
+ 'extent-len': 'uint64'
+ }
+}
+
+##
+# @cxl-release-dynamic-capacity-event:
+#
+# Command to add dynamic capacity extent event
+#
+# @path: CXL DCD canonical QOM path
+# @region-id: region id
+# @num-extent: number of extents to add, test only
+# @dpa: start dpa for the operation
+# @extent-len: extent size in MB
+#
+# Since: 8.0
+##
+{ 'command': 'cxl-release-dynamic-capacity-event',
+ 'data': { 'path': 'str',
+ 'region-id': 'uint8',
+ 'num-extent': 'uint32',
+ 'dpa':'uint64',
+ 'extent-len': 'uint64'
+ }
+}
--
2.25.1
- [Qemu RFC 0/7] Early enabling of DCD emulation in Qemu, Fan Ni, 2023/05/11
- Message not available
- Message not available
- Message not available
- [RFC 6/7] Add qmp interfaces to add/release dynamic capacity extents,
Fan Ni <=
- Message not available
- Message not available
- Message not available
Re: [Qemu RFC 0/7] Early enabling of DCD emulation in Qemu, Jonathan Cameron, 2023/05/15