[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH v4 09/10] hw/cxl/events: Add qmp interfaces to add/release dy
From: |
Jonathan Cameron |
Subject: |
Re: [PATCH v4 09/10] hw/cxl/events: Add qmp interfaces to add/release dynamic capacity extents |
Date: |
Mon, 26 Feb 2024 18:10:21 +0000 |
On Wed, 21 Feb 2024 10:16:02 -0800
nifan.cxl@gmail.com wrote:
> From: Fan Ni <fan.ni@samsung.com>
>
> Since fabric manager emulation is not supported yet, the change implements
> the functions to add/release dynamic capacity extents as QMP interfaces.
>
> Note: we skips any FM issued extent release request if the exact extent
> does not exist in the extent list of the device. We will loose the
> restriction later once we have partial release support in the kernel.
>
> 1. Add dynamic capacity extents:
>
> For example, the command to add two continuous extents (each 128MiB long)
> to region 0 (starting at DPA offset 0) looks like below:
>
> { "execute": "qmp_capabilities" }
>
> { "execute": "cxl-add-dynamic-capacity",
> "arguments": {
> "path": "/machine/peripheral/cxl-dcd0",
> "region-id": 0,
> "extents": [
> {
> "dpa": 0,
> "len": 134217728
> },
> {
> "dpa": 134217728,
> "len": 134217728
> }
> ]
> }
> }
>
> 2. Release dynamic capacity extents:
>
> For example, the command to release an extent of size 128MiB from region 0
> (DPA offset 128MiB) look like below:
>
> { "execute": "cxl-release-dynamic-capacity",
> "arguments": {
> "path": "/machine/peripheral/cxl-dcd0",
> "region-id": 0,
> "extents": [
> {
> "dpa": 134217728,
> "len": 134217728
> }
> ]
> }
> }
>
> Signed-off-by: Fan Ni <fan.ni@samsung.com>
A few things inline. I don't understand one of the comments.
> ---
>
> diff --git a/hw/mem/cxl_type3.c b/hw/mem/cxl_type3.c
> index f4edada303..b8c4273e99 100644
> --- a/hw/mem/cxl_type3.c
> +++ b/hw/mem/cxl_type3.c
> +/*
> + * Check whether the exact extent exists in the list
> + * Return value: the extent pointer in the list; else null
> + */
> +static CXLDCExtent *cxl_dc_extent_exists(CXLDCExtentList *list,
> + CXLDCExtentRaw *ext)
> +{
> + CXLDCExtent *ent;
> +
> + if (!ext || !list) {
> + return NULL;
> + }
> +
> + QTAILQ_FOREACH(ent, list, node) {
> + if (ent->start_dpa != ext->start_dpa) {
> + continue;
> + }
> +
> + /*Found exact extent*/
Spacing /* Found .. extent */
> + return ent->len == ext->len ? ent : NULL;
> + }
> +
> + return NULL;
> +}
> +
> +/*
> + * The main function to process dynamic capacity event. Currently DC extents
> + * add/release requests are processed.
> + */
> +static void qmp_cxl_process_dynamic_capacity(const char *path, CxlEventLog
> log,
> + CXLDCEventType type, uint16_t
> hid,
> + uint8_t rid,
> + CXLDCExtentRecordList *records,
> + Error **errp)
> +{
> + Object *obj;
> + CXLEventDynamicCapacity dCap = {};
> + CXLEventRecordHdr *hdr = &dCap.hdr;
> + CXLType3Dev *dcd;
> + uint8_t flags = 1 << CXL_EVENT_TYPE_INFO;
> + uint32_t num_extents = 0;
> + CXLDCExtentRecordList *list;
> + g_autofree CXLDCExtentRaw *extents = NULL;
> + uint8_t enc_log;
> + uint64_t offset, len, block_size;
> + int i;
> + int rc;
> + g_autofree unsigned long *blk_bitmap = NULL;
> +
> + obj = object_resolve_path(path, NULL);
> + 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);
> + if (!dcd->dc.num_regions) {
> + error_setg(errp, "No dynamic capacity support from the device");
> + return;
> + }
> +
> + rc = ct3d_qmp_cxl_event_log_enc(log);
> + if (rc < 0) {
> + error_setg(errp, "Unhandled error log type");
> + return;
> + }
> + enc_log = rc;
> +
> + if (rid >= dcd->dc.num_regions) {
> + error_setg(errp, "region id is too large");
> + return;
> + }
> + block_size = dcd->dc.regions[rid].block_size;
> +
> + /* Sanity check and count the extents */
> + list = records;
> + while (list) {
> + offset = list->value->offset;
> + len = list->value->len;
> +
> + if (len == 0) {
> + error_setg(errp, "extent with 0 length is not allowed");
> + return;
> + }
> +
> + if (offset % block_size || len % block_size) {
> + error_setg(errp, "dpa or len is not aligned to region block
> size");
> + return;
> + }
> +
> + if (offset + len > dcd->dc.regions[rid].len) {
> + error_setg(errp, "extent range is beyond the region end");
> + return;
> + }
> +
> + num_extents++;
> + list = list->next;
> + }
> + if (num_extents == 0) {
> + error_setg(errp, "No extents found in the command");
> + return;
> + }
> +
> + blk_bitmap = bitmap_new(dcd->dc.regions[rid].len / block_size);
> +
> + /* Create Extent list for event being passed to host */
> + i = 0;
> + list = records;
> + extents = g_new0(CXLDCExtentRaw, num_extents);
> + while (list) {
> + CXLDCExtent *ent;
> + bool skip_extent = false;
> +
> + offset = list->value->offset;
> + len = list->value->len;
> +
> + extents[i].start_dpa = offset + dcd->dc.regions[rid].base;
> + extents[i].len = len;
> + memset(extents[i].tag, 0, 0x10);
> + extents[i].shared_seq = 0;
> +
> + if (type == DC_EVENT_RELEASE_CAPACITY ||
> + type == DC_EVENT_FORCED_RELEASE_CAPACITY) {
> + /*
> + * if the extent is still pending to be added to the host,
> + * remove it from the pending extent list, so later when the add
> + * response for the extent arrives, the device can reject the
> + * extent as it is not in the pending list.
> + */
> + ent = cxl_dc_extent_exists(&dcd->dc.extents_pending_to_add,
> + &extents[i]);
> + if (ent) {
> + QTAILQ_REMOVE(&dcd->dc.extents_pending_to_add, ent, node);
> + g_free(ent);
> + skip_extent = true;
> + } else if (!cxl_dc_extent_exists(&dcd->dc.extents, &extents[i]))
> {
> + /* If the exact extent is not in the accepted list, skip */
> + skip_extent = true;
> + }
> + }
> +
> + /* No duplicate or overlapped extents are allowed */
> + if (test_any_bits_set(blk_bitmap, offset / block_size,
> + len / block_size)) {
> + error_setg(errp, "duplicate or overlapped extents are detected");
> + return;
> + }
> + bitmap_set(blk_bitmap, offset / block_size, len / block_size);
> +
> + list = list->next;
> + if (!skip_extent) {
> + i++;
> + }
> + }
> + num_extents = i;
> +
> + switch (type) {
> + case DC_EVENT_ADD_CAPACITY:
> + break;
> + default:
> + break;
> + }
> + /*
> + * CXL r3.1 section 8.2.9.2.1.6: Dynamic Capacity Event Record
> + *
> + * 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.
> + */
> + cxl_assign_event_header(hdr, &dynamic_capacity_uuid, flags, sizeof(dCap),
> + cxl_device_get_timestamp(&dcd->cxl_dstate));
> +
> + dCap.type = type;
> + /* FIXME: for now, validaity flag is cleared */
spelling
> + dCap.validity_flags = 0;
> + stw_le_p(&dCap.host_id, hid);
> + /* only valid for DC_REGION_CONFIG_UPDATED event */
> + dCap.updated_region_id = 0;
> + /*
> + * FIXME: for now, "More" flag is cleared as there is only one extent for
> + * each record
This need more info. If they have the same tag then should set more on the
records.
> + */
> + dCap.flags = 0;
> +
> + /*
> + * For current implementation, each DC event record only associates with
> + * one extent, so the "More" flag does not need to be set.
> + */
> + for (i = 0; i < num_extents; i++) {
> + memcpy(&dCap.dynamic_capacity_extent, &extents[i],
> + sizeof(CXLDCExtentRaw));
> +
> + if (type == DC_EVENT_ADD_CAPACITY) {
> + cxl_insert_extent_to_extent_list(&dcd->dc.extents_pending_to_add,
> + extents[i].start_dpa,
> + extents[i].len,
> + extents[i].tag,
> + extents[i].shared_seq);
> + }
> +
> + if (cxl_event_insert(&dcd->cxl_dstate, enc_log,
> + (CXLEventRecordRaw *)&dCap)) {
> + cxl_event_irq_assert(dcd);
> + }
> + }
> +}
- [PATCH v4 05/10] hw/mem/cxl-type3: Refactor ct3_build_cdat_entries_for_mr to take mr size insead of mr as argument, (continued)
- [PATCH v4 05/10] hw/mem/cxl-type3: Refactor ct3_build_cdat_entries_for_mr to take mr size insead of mr as argument, nifan . cxl, 2024/02/21
- [PATCH v4 06/10] hw/mem/cxl_type3: Add host backend and address space handling for DC regions, nifan . cxl, 2024/02/21
- [PATCH v4 07/10] hw/mem/cxl_type3: Add DC extent list representative and get DC extent list mailbox support, nifan . cxl, 2024/02/21
- [PATCH v4 10/10] hw/mem/cxl_type3: Add dpa range validation for accesses to DC regions, nifan . cxl, 2024/02/21
- [PATCH v4 09/10] hw/cxl/events: Add qmp interfaces to add/release dynamic capacity extents, nifan . cxl, 2024/02/21
- [PATCH v4 08/10] hw/cxl/cxl-mailbox-utils: Add mailbox commands to support add/release dynamic capacity response, nifan . cxl, 2024/02/21
- Re: [PATCH v4 08/10] hw/cxl/cxl-mailbox-utils: Add mailbox commands to support add/release dynamic capacity response, fan, 2024/02/26
Message not available
Message not available