From: Jonathan Cameron <Jonathan.Cameron@Huawei.com>
To: Gregory Price <gregory.price@memverge.com>
Cc: <nifan.cxl@gmail.com>, <qemu-devel@nongnu.org>,
<linux-cxl@vger.kernel.org>, <ira.weiny@intel.com>,
<dan.j.williams@intel.com>, <a.manzanares@samsung.com>,
<dave@stgolabs.net>, <nmtadam.samsung@gmail.com>,
<jim.harris@samsung.com>, <Jorgen.Hansen@wdc.com>,
<wj28.lee@gmail.com>, Fan Ni <fan.ni@samsung.com>
Subject: Re: [PATCH v6 09/12] hw/cxl/events: Add qmp interfaces to add/release dynamic capacity extents
Date: Fri, 5 Apr 2024 13:27:19 +0100 [thread overview]
Message-ID: <20240405132719.00005859@Huawei.com> (raw)
In-Reply-To: <Zg2c+YauNGqhFfTW@memverge.com>
On Wed, 3 Apr 2024 14:16:25 -0400
Gregory Price <gregory.price@memverge.com> wrote:
A few follow up comments.
> On Mon, Mar 25, 2024 at 12:02:27PM -0700, nifan.cxl@gmail.com wrote:
> > From: Fan Ni <fan.ni@samsung.com>
> >
> > To simulate FM functionalities for initiating Dynamic Capacity Add
> > (Opcode 5604h) and Dynamic Capacity Release (Opcode 5605h) as in CXL spec
> > r3.1 7.6.7.6.5 and 7.6.7.6.6, we implemented two QMP interfaces to issue
> > add/release dynamic capacity extents requests.
> >
> ... snip
> > +
> > +/*
> > + * 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)
> > +{
> ... snip
> > + /* Sanity check and count the extents */
> > + list = records;
> > + while (list) {
> > + offset = list->value->offset;
> > + len = list->value->len;
> > + dpa = offset + dcd->dc.regions[rid].base;
> > +
> > + 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;
> > + }
> > +
> > + /* 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);
> > +
> > + num_extents++;
>
> I think num_extents is always equal to the length of the list, otherwise
> this code will return with error.
>
> Nitpick:
> This can be moved to the bottom w/ `list = list->next` to express that a
> little more clearly.
>
> > + if (type == DC_EVENT_RELEASE_CAPACITY) {
> > + if (cxl_extents_overlaps_dpa_range(&dcd->dc.extents_pending,
> > + dpa, len)) {
> > + error_setg(errp,
> > + "cannot release extent with pending DPA range");
> > + return;
> > + }
> > + if (!cxl_extents_contains_dpa_range(&dcd->dc.extents,
> > + dpa, len)) {
> > + error_setg(errp,
> > + "cannot release extent with non-existing DPA range");
> > + return;
> > + }
> > + }
> > + list = list->next;
> > + }
> > +
> > + if (num_extents == 0) {
>
> Since num_extents is always the length of the list, this is equivalent to
> `if (!records)` prior to the while loop. Makes it a little more clear that:
>
> 1. There must be at least 1 extent
> 2. All extents must be valid for the command to be serviced.
Agreed.
>
> > + error_setg(errp, "no valid extents to send to process");
> > + return;
> > + }
> > +
>
> I'm looking at adding the MHD extensions around this point, e.g.:
>
> /* If MHD cannot allocate requested extents, the cmd fails */
> if (type == DC_EVENT_ADD_CAPACITY && dcd->mhd_dcd_extents_allocate &&
> num_extents != dcd->mhd_dcd_extents_allocate(...))
> return;
>
> where mhd_dcd_extents_allocate checks the MHD block bitmap and tags
> for correctness (shared // no double-allocations, etc). On success,
> it garuantees proper ownership.
>
> the release path would then be done in the release response path from
> the host, as opposed to the release event injection.
I think it would be polite to check if the QMP command on release
for whether it is asking something plausible - makes for an easier
to user QMP interface. I guess it's not strictly required though.
What races are there on release? We aren't support force release
for now, and for anything else, it's host specific (unlike add where
the extra rules kick in). AS such I 'think' a check at command
time will be valid as long as the host hasn't done an async
release of capacity between that and the event record. That
is a race we always have and the host should at most log it and
not release capacity twice.
>
> Do you see any issues with that flow?
>
> > + /* Create extent list for event being passed to host */
> > + i = 0;
> > + list = records;
> > + extents = g_new0(CXLDCExtentRaw, num_extents);
> > + while (list) {
> > + offset = list->value->offset;
> > + len = list->value->len;
> > + dpa = dcd->dc.regions[rid].base + offset;
> > +
> > + extents[i].start_dpa = dpa;
> > + extents[i].len = len;
> > + memset(extents[i].tag, 0, 0x10);
> > + extents[i].shared_seq = 0;
> > + list = list->next;
> > + i++;
> > + }
> > +
> > + /*
> > + * 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, validity flag is cleared */
> > + 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, the "More" flag is cleared as there is only one
> > + * extent associating with each record and tag-based release is
> > + * not supported.
> > + */
> > + dCap.flags = 0;
> > + 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,
> > + 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)) {
>
> Pardon if I missed a prior discussion about this, but what happens to
> pending events in the scenario where cxl_event_insert fails?
For an add or release, error returned to the FM that tried it.
For Force release, carry on regardless (setting overflow etc).
Host goes boom but that probably happens anyway :)
Jonathan
>
> ~Gregory
WARNING: multiple messages have this Message-ID (diff)
From: Jonathan Cameron via <qemu-devel@nongnu.org>
To: Gregory Price <gregory.price@memverge.com>
Cc: <nifan.cxl@gmail.com>, <qemu-devel@nongnu.org>,
<linux-cxl@vger.kernel.org>, <ira.weiny@intel.com>,
<dan.j.williams@intel.com>, <a.manzanares@samsung.com>,
<dave@stgolabs.net>, <nmtadam.samsung@gmail.com>,
<jim.harris@samsung.com>, <Jorgen.Hansen@wdc.com>,
<wj28.lee@gmail.com>, Fan Ni <fan.ni@samsung.com>
Subject: Re: [PATCH v6 09/12] hw/cxl/events: Add qmp interfaces to add/release dynamic capacity extents
Date: Fri, 5 Apr 2024 13:27:19 +0100 [thread overview]
Message-ID: <20240405132719.00005859@Huawei.com> (raw)
In-Reply-To: <Zg2c+YauNGqhFfTW@memverge.com>
On Wed, 3 Apr 2024 14:16:25 -0400
Gregory Price <gregory.price@memverge.com> wrote:
A few follow up comments.
> On Mon, Mar 25, 2024 at 12:02:27PM -0700, nifan.cxl@gmail.com wrote:
> > From: Fan Ni <fan.ni@samsung.com>
> >
> > To simulate FM functionalities for initiating Dynamic Capacity Add
> > (Opcode 5604h) and Dynamic Capacity Release (Opcode 5605h) as in CXL spec
> > r3.1 7.6.7.6.5 and 7.6.7.6.6, we implemented two QMP interfaces to issue
> > add/release dynamic capacity extents requests.
> >
> ... snip
> > +
> > +/*
> > + * 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)
> > +{
> ... snip
> > + /* Sanity check and count the extents */
> > + list = records;
> > + while (list) {
> > + offset = list->value->offset;
> > + len = list->value->len;
> > + dpa = offset + dcd->dc.regions[rid].base;
> > +
> > + 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;
> > + }
> > +
> > + /* 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);
> > +
> > + num_extents++;
>
> I think num_extents is always equal to the length of the list, otherwise
> this code will return with error.
>
> Nitpick:
> This can be moved to the bottom w/ `list = list->next` to express that a
> little more clearly.
>
> > + if (type == DC_EVENT_RELEASE_CAPACITY) {
> > + if (cxl_extents_overlaps_dpa_range(&dcd->dc.extents_pending,
> > + dpa, len)) {
> > + error_setg(errp,
> > + "cannot release extent with pending DPA range");
> > + return;
> > + }
> > + if (!cxl_extents_contains_dpa_range(&dcd->dc.extents,
> > + dpa, len)) {
> > + error_setg(errp,
> > + "cannot release extent with non-existing DPA range");
> > + return;
> > + }
> > + }
> > + list = list->next;
> > + }
> > +
> > + if (num_extents == 0) {
>
> Since num_extents is always the length of the list, this is equivalent to
> `if (!records)` prior to the while loop. Makes it a little more clear that:
>
> 1. There must be at least 1 extent
> 2. All extents must be valid for the command to be serviced.
Agreed.
>
> > + error_setg(errp, "no valid extents to send to process");
> > + return;
> > + }
> > +
>
> I'm looking at adding the MHD extensions around this point, e.g.:
>
> /* If MHD cannot allocate requested extents, the cmd fails */
> if (type == DC_EVENT_ADD_CAPACITY && dcd->mhd_dcd_extents_allocate &&
> num_extents != dcd->mhd_dcd_extents_allocate(...))
> return;
>
> where mhd_dcd_extents_allocate checks the MHD block bitmap and tags
> for correctness (shared // no double-allocations, etc). On success,
> it garuantees proper ownership.
>
> the release path would then be done in the release response path from
> the host, as opposed to the release event injection.
I think it would be polite to check if the QMP command on release
for whether it is asking something plausible - makes for an easier
to user QMP interface. I guess it's not strictly required though.
What races are there on release? We aren't support force release
for now, and for anything else, it's host specific (unlike add where
the extra rules kick in). AS such I 'think' a check at command
time will be valid as long as the host hasn't done an async
release of capacity between that and the event record. That
is a race we always have and the host should at most log it and
not release capacity twice.
>
> Do you see any issues with that flow?
>
> > + /* Create extent list for event being passed to host */
> > + i = 0;
> > + list = records;
> > + extents = g_new0(CXLDCExtentRaw, num_extents);
> > + while (list) {
> > + offset = list->value->offset;
> > + len = list->value->len;
> > + dpa = dcd->dc.regions[rid].base + offset;
> > +
> > + extents[i].start_dpa = dpa;
> > + extents[i].len = len;
> > + memset(extents[i].tag, 0, 0x10);
> > + extents[i].shared_seq = 0;
> > + list = list->next;
> > + i++;
> > + }
> > +
> > + /*
> > + * 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, validity flag is cleared */
> > + 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, the "More" flag is cleared as there is only one
> > + * extent associating with each record and tag-based release is
> > + * not supported.
> > + */
> > + dCap.flags = 0;
> > + 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,
> > + 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)) {
>
> Pardon if I missed a prior discussion about this, but what happens to
> pending events in the scenario where cxl_event_insert fails?
For an add or release, error returned to the FM that tried it.
For Force release, carry on regardless (setting overflow etc).
Host goes boom but that probably happens anyway :)
Jonathan
>
> ~Gregory
next prev parent reply other threads:[~2024-04-05 12:27 UTC|newest]
Thread overview: 65+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-03-25 19:02 [PATCH v6 00/12] Enabling DCD emulation support in Qemu nifan.cxl
2024-03-25 19:02 ` [PATCH v6 01/12] hw/cxl/cxl-mailbox-utils: Add dc_event_log_size field to output payload of identify memory device command nifan.cxl
2024-03-25 19:02 ` [PATCH v6 02/12] hw/cxl/cxl-mailbox-utils: Add dynamic capacity region representative and mailbox command support nifan.cxl
2024-03-25 19:02 ` [PATCH v6 03/12] include/hw/cxl/cxl_device: Rename mem_size as static_mem_size for type3 memory devices nifan.cxl
2024-03-25 19:02 ` [PATCH v6 04/12] hw/mem/cxl_type3: Add support to create DC regions to " nifan.cxl
2024-03-25 19:02 ` [PATCH v6 05/12] hw/mem/cxl-type3: Refactor ct3_build_cdat_entries_for_mr to take mr size instead of mr as argument nifan.cxl
2024-03-25 19:02 ` [PATCH v6 06/12] hw/mem/cxl_type3: Add host backend and address space handling for DC regions nifan.cxl
2024-04-05 10:58 ` Jonathan Cameron
2024-04-05 10:58 ` Jonathan Cameron via
2024-03-25 19:02 ` [PATCH v6 07/12] hw/mem/cxl_type3: Add DC extent list representative and get DC extent list mailbox support nifan.cxl
2024-04-05 11:08 ` Jonathan Cameron
2024-04-05 11:08 ` Jonathan Cameron via
2024-03-25 19:02 ` [PATCH v6 08/12] hw/cxl/cxl-mailbox-utils: Add mailbox commands to support add/release dynamic capacity response nifan.cxl
2024-04-04 13:32 ` Jørgen Hansen
2024-04-05 11:12 ` Jonathan Cameron
2024-04-05 11:12 ` Jonathan Cameron via
2024-04-09 19:21 ` fan
2024-04-15 17:56 ` fan
2024-04-16 10:02 ` Jørgen Hansen
2024-04-16 16:27 ` fan
2024-04-15 18:00 ` fan
2024-04-05 11:39 ` Jonathan Cameron
2024-04-05 11:39 ` Jonathan Cameron via
2024-03-25 19:02 ` [PATCH v6 09/12] hw/cxl/events: Add qmp interfaces to add/release dynamic capacity extents nifan.cxl
2024-04-03 18:16 ` Gregory Price
2024-04-05 12:27 ` Jonathan Cameron [this message]
2024-04-05 12:27 ` Jonathan Cameron via
2024-04-05 16:07 ` Gregory Price
2024-04-05 17:44 ` Jonathan Cameron
2024-04-05 17:44 ` Jonathan Cameron via
2024-04-05 18:09 ` Gregory Price
2024-04-09 16:10 ` Jonathan Cameron
2024-04-09 16:10 ` Jonathan Cameron via
2024-04-05 12:18 ` Jonathan Cameron
2024-04-05 12:18 ` Jonathan Cameron via
2024-04-09 21:26 ` fan
2024-04-10 19:49 ` Jonathan Cameron
2024-04-10 19:49 ` Jonathan Cameron via
2024-04-15 20:06 ` fan
2024-04-16 14:58 ` Jonathan Cameron
2024-04-16 14:58 ` Jonathan Cameron via
2024-04-16 16:52 ` fan
2024-04-17 11:50 ` Jonathan Cameron
2024-04-17 11:50 ` Jonathan Cameron via
2024-04-16 17:14 ` Gregory Price
2024-03-25 19:02 ` [PATCH v6 10/12] hw/mem/cxl_type3: Add dpa range validation for accesses to DC regions nifan.cxl
2024-04-05 12:29 ` Jonathan Cameron
2024-04-05 12:29 ` Jonathan Cameron via
2024-04-12 22:54 ` Gregory Price
2024-04-15 17:37 ` fan
2024-04-16 15:00 ` Jonathan Cameron
2024-04-16 15:00 ` Jonathan Cameron via
2024-04-16 16:37 ` fan
2024-04-17 11:59 ` Jonathan Cameron
2024-04-17 11:59 ` Jonathan Cameron via
2024-04-18 17:58 ` Gregory Price
2024-04-16 17:15 ` Gregory Price
2024-03-25 19:02 ` [PATCH v6 11/12] hw/cxl/cxl-mailbox-utils: Add superset extent release mailbox support nifan.cxl
2024-04-05 9:57 ` Jørgen Hansen
2024-04-15 20:17 ` fan
2024-04-05 12:32 ` Jonathan Cameron
2024-04-05 12:32 ` Jonathan Cameron via
2024-03-25 19:02 ` [PATCH v6 12/12] hw/mem/cxl_type3: Allow to release extent superset in QMP interface nifan.cxl
2024-04-05 12:33 ` Jonathan Cameron
2024-04-05 12:33 ` Jonathan Cameron via
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=20240405132719.00005859@Huawei.com \
--to=jonathan.cameron@huawei.com \
--cc=Jorgen.Hansen@wdc.com \
--cc=a.manzanares@samsung.com \
--cc=dan.j.williams@intel.com \
--cc=dave@stgolabs.net \
--cc=fan.ni@samsung.com \
--cc=gregory.price@memverge.com \
--cc=ira.weiny@intel.com \
--cc=jim.harris@samsung.com \
--cc=linux-cxl@vger.kernel.org \
--cc=nifan.cxl@gmail.com \
--cc=nmtadam.samsung@gmail.com \
--cc=qemu-devel@nongnu.org \
--cc=wj28.lee@gmail.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.