All of lore.kernel.org
 help / color / mirror / Atom feed
From: Fan Ni <fan.ni@gmx.us>
To: J?rgen Hansen <Jorgen.Hansen@wdc.com>
Cc: Fan Ni <fan.ni@samsung.com>,
	"qemu-devel@nongnu.org" <qemu-devel@nongnu.org>,
	"jonathan.cameron@huawei.com" <jonathan.cameron@huawei.com>,
	"linux-cxl@vger.kernel.org" <linux-cxl@vger.kernel.org>,
	"gregory.price@memverge.com" <gregory.price@memverge.com>,
	"hchkuo@avery-design.com.tw" <hchkuo@avery-design.com.tw>,
	"cbrowy@avery-design.com" <cbrowy@avery-design.com>,
	"ira.weiny@intel.com" <ira.weiny@intel.com>,
	"dan.j.williams@intel.com" <dan.j.williams@intel.com>,
	Adam Manzanares <a.manzanares@samsung.com>,
	"dave@stgolabs.net" <dave@stgolabs.net>,
	"nmtadam.samsung@gmail.com" <nmtadam.samsung@gmail.com>,
	"nifan@outlook.com" <nifan@outlook.com>
Subject: Re: [Qemu PATCH v2 7/9] hw/cxl/cxl-mailbox-utils: Add mailbox commands to support add/release dynamic capacity response
Date: Fri, 8 Sep 2023 10:19:55 -0700	[thread overview]
Message-ID: <ZPtXuyJkFKgBpL9A@debian> (raw)
In-Reply-To: <e1640028-6b9d-3cdf-52fb-241f985c4bbb@wdc.com>

On Fri, Sep 08, 2023 at 01:00:16PM +0000, J?rgen Hansen wrote:
> On 7/25/23 20:39, Fan Ni wrote:
> > From: Fan Ni <nifan@outlook.com>
> >
> > Per CXL spec 3.0, two mailbox commands are implemented:
> > Add Dynamic Capacity Response (Opcode 4802h) 8.2.9.8.9.3, and
> > Release Dynamic Capacity (Opcode 4803h) 8.2.9.8.9.4.
> >
> > Signed-off-by: Fan Ni <fan.ni@samsung.com>
> > ---
> >   hw/cxl/cxl-mailbox-utils.c  | 253 ++++++++++++++++++++++++++++++++++++
> >   include/hw/cxl/cxl_device.h |   3 +-
> >   2 files changed, 255 insertions(+), 1 deletion(-)
> >
> > diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c
> > index 3d25a9697e..1e4944da95 100644
> > --- a/hw/cxl/cxl-mailbox-utils.c
> > +++ b/hw/cxl/cxl-mailbox-utils.c
> > @@ -84,6 +84,8 @@ enum {
> >       DCD_CONFIG  = 0x48, /*r3.0: 8.2.9.8.9*/
> >           #define GET_DC_CONFIG          0x0
> >           #define GET_DYN_CAP_EXT_LIST   0x1
> > +        #define ADD_DYN_CAP_RSP        0x2
> > +        #define RELEASE_DYN_CAP        0x3
> >       PHYSICAL_SWITCH = 0x51
> >           #define IDENTIFY_SWITCH_DEVICE      0x0
> >   };
> > @@ -1086,6 +1088,251 @@ static CXLRetCode cmd_dcd_get_dyn_cap_ext_list(struct cxl_cmd *cmd,
> >       return CXL_MBOX_SUCCESS;
> >   }
> >
> > +/*
> > + * Check whether the bits at addr between [nr, nr+size) are all set,
> > + * return 1 if all 1s, else return 0
> > + */
> > +static inline int test_bits(const unsigned long *addr, int nr, int size)
> > +{
> > +    unsigned long res = find_next_zero_bit(addr, size + nr, nr);
> > +
> > +    return (res >= nr + size) ? 1 : 0;
> > +}
> > +
> > +/*
> > + * Find dynamic capacity region id based on dpa range [dpa, dpa+len)
> > + */
> > +static uint8_t find_region_id(struct CXLType3Dev *dev, uint64_t dpa,
> > +        uint64_t len)
> > +{
> > +    int8_t i = dev->dc.num_regions - 1;
> > +
> > +    while (i > 0 && dpa < dev->dc.regions[i].base) {
> > +        i--;
> > +    }
> > +
> > +    if (dpa < dev->dc.regions[i].base
> > +            || dpa + len > dev->dc.regions[i].base + dev->dc.regions[i].len) {
> > +        return dev->dc.num_regions;
> > +    }
> > +
> > +    return i;
> > +}
> > +
> > +static void insert_extent_to_extent_list(CXLDCDExtentList *list, uint64_t dpa,
> > +        uint64_t len, uint8_t *tag, uint16_t shared_seq)
> > +{
> > +    CXLDCD_Extent *extent;
> > +    extent = g_new0(CXLDCD_Extent, 1);
> > +    extent->start_dpa = dpa;
> > +    extent->len = len;
> > +    if (tag) {
> > +        memcpy(extent->tag, tag, 0x10);
> > +    } else {
> > +        memset(extent->tag, 0, 0x10);
> > +    }
> > +    extent->shared_seq = shared_seq;
> > +
> > +    QTAILQ_INSERT_TAIL(list, extent, node);
> > +}
> > +
> > +typedef struct updated_dc_extent_list_in_pl {
> > +    uint32_t num_entries_updated;
> > +    uint8_t rsvd[4];
> > +    struct { /* r3.0: Table 8-130 */
> > +        uint64_t start_dpa;
> > +        uint64_t len;
> > +        uint8_t rsvd[8];
> > +    } QEMU_PACKED updated_entries[];
> > +} QEMU_PACKED updated_dc_extent_list_in_pl;
> > +
> > +/*
> > + * The function only check the input extent list against itself.
> > + */
> > +static CXLRetCode detect_malformed_extent_list(CXLType3Dev *dev,
> > +        const updated_dc_extent_list_in_pl *in)
> > +{
> > +    unsigned long *blk_bitmap;
> > +    uint64_t min_block_size = dev->dc.regions[0].block_size;
> > +    struct CXLDCD_Region *region = &dev->dc.regions[0];
> > +    uint32_t i;
> > +    uint64_t dpa, len;
> > +    uint8_t rid;
> > +    CXLRetCode ret;
> > +
> > +    for (i = 1; i < dev->dc.num_regions; i++) {
> > +        region = &dev->dc.regions[i];
> > +        if (min_block_size > region->block_size) {
> > +            min_block_size = region->block_size;
> > +        }
> > +    }
> > +
> > +    blk_bitmap = bitmap_new((region->len + region->base
> > +                - dev->dc.regions[0].base) / min_block_size);
> > +
> > +    for (i = 0; i < in->num_entries_updated; i++) {
> > +        dpa = in->updated_entries[i].start_dpa;
> > +        len = in->updated_entries[i].len;
> > +
> > +        rid = find_region_id(dev, dpa, len);
> > +        if (rid == dev->dc.num_regions) {
> > +            ret = CXL_MBOX_INVALID_PA;
> > +            goto out;
> > +        }
> > +
> > +        region = &dev->dc.regions[rid];
> > +        if (dpa % region->block_size || len % region->block_size) {
> > +            ret = CXL_MBOX_INVALID_EXTENT_LIST;
> > +            goto out;
> > +        }
>
> Hi,
>
> The bitmap uses the dc region 0 base address as the baseline, so when
> checking the dpa against the bitmap it needs to be adjusted for that
> before the bitmap checks, e.g.,
>
> +        dpa -= dev->dc.regions[0].base;
>
> Thanks,
> Jorgen

Make sense. Will fix. Thanks.

Fan
>
> > +        /* the dpa range already covered by some other extents in the list */
> > +        if (test_bits(blk_bitmap, dpa / min_block_size, len / min_block_size)) {
> > +            ret = CXL_MBOX_INVALID_EXTENT_LIST;
> > +            goto out;
> > +        }
> > +        bitmap_set(blk_bitmap, dpa / min_block_size, len / min_block_size);
> > +   }
> > +
> > +    ret = CXL_MBOX_SUCCESS;
> > +
> > +out:
> > +    g_free(blk_bitmap);
> > +    return ret;
> > +}
> > +
> > +/*
> > + * cxl spec 3.0: 8.2.9.8.9.3
> > + * Add Dynamic Capacity Response (opcode 4802h)
> > + * Assume an extent is added only after the response is processed successfully
> > + * TODO: for better extent list validation, a better solution would be
> > + * maintaining a pending extent list and use it to verify the extent list in
> > + * the response.
> > + */
> > +static CXLRetCode cmd_dcd_add_dyn_cap_rsp(struct cxl_cmd *cmd,
> > +        CXLDeviceState *cxl_dstate, uint16_t *len_unused)
> > +{
> > +    updated_dc_extent_list_in_pl *in = (void *)cmd->payload;
> > +    struct CXLType3Dev *ct3d = container_of(cxl_dstate, CXLType3Dev,
> > +            cxl_dstate);
> > +    CXLDCDExtentList *extent_list = &ct3d->dc.extents;
> > +    CXLDCD_Extent *ent;
> > +    uint32_t i;
> > +    uint64_t dpa, len;
> > +    CXLRetCode ret;
> > +
> > +    if (in->num_entries_updated == 0) {
> > +        ret = CXL_MBOX_SUCCESS;
> > +        goto out;
> > +    }
> > +
> > +    ret = detect_malformed_extent_list(ct3d, in);
> > +    if (ret != CXL_MBOX_SUCCESS) {
> > +        goto out;
> > +    }
> > +
> > +    for (i = 0; i < in->num_entries_updated; i++) {
> > +        dpa = in->updated_entries[i].start_dpa;
> > +        len = in->updated_entries[i].len;
> > +
> > +        /*
> > +         * Check if the DPA range of the to-be-added extent overlaps with
> > +         * existing extent list maintained by the device.
> > +         */
> > +        QTAILQ_FOREACH(ent, extent_list, node) {
> > +            if (ent->start_dpa == dpa && ent->len == len) {
> > +                ret = CXL_MBOX_INVALID_PA;
> > +                goto out;
> > +            } else if (ent->start_dpa <= dpa
> > +                    && dpa + len <= ent->start_dpa + ent->len) {
> > +                ret = CXL_MBOX_INVALID_PA;
> > +                goto out;
> > +            } else if ((dpa < ent->start_dpa + ent->len
> > +                        && dpa + len > ent->start_dpa + ent->len)
> > +                    || (dpa < ent->start_dpa && dpa + len > ent->start_dpa)) {
> > +                ret = CXL_MBOX_INVALID_PA;
> > +                goto out;
> > +            }
> > +        }
> > +
> > +        /*
> > +         * TODO: add a pending extent list based on event log record and verify
> > +         * the input response
> > +         */
> > +
> > +        insert_extent_to_extent_list(extent_list, dpa, len, NULL, 0);
> > +    }
> > +    ret = CXL_MBOX_SUCCESS;
> > +
> > +out:
> > +    return ret;
> > +}
> > +
> > +/*
> > + * Spec 3.0: 8.2.9.8.9.4
> > + * Release Dynamic Capacity (opcode 4803h)
> > + **/
> > +static CXLRetCode cmd_dcd_release_dyn_cap(struct cxl_cmd *cmd,
> > +        CXLDeviceState *cxl_dstate,
> > +        uint16_t *len_unused)
> > +{
> > +    updated_dc_extent_list_in_pl *in = (void *)cmd->payload;
> > +    struct CXLType3Dev *ct3d = container_of(cxl_dstate, CXLType3Dev,
> > +            cxl_dstate);
> > +    CXLDCDExtentList *extent_list = &ct3d->dc.extents;
> > +    CXLDCD_Extent *ent;
> > +    uint32_t i;
> > +    uint64_t dpa, len;
> > +    CXLRetCode ret;
> > +
> > +    if (in->num_entries_updated == 0) {
> > +        return CXL_MBOX_INVALID_INPUT;
> > +    }
> > +
> > +    ret = detect_malformed_extent_list(ct3d, in);
> > +    if (ret != CXL_MBOX_SUCCESS) {
> > +        return ret;
> > +    }
> > +
> > +    for (i = 0; i < in->num_entries_updated; i++) {
> > +        dpa = in->updated_entries[i].start_dpa;
> > +        len = in->updated_entries[i].len;
> > +
> > +        QTAILQ_FOREACH(ent, extent_list, node) {
> > +            if (ent->start_dpa == dpa && ent->len == len) {
> > +                break;
> > +            } else if (ent->start_dpa < dpa
> > +                    && dpa + len <= ent->start_dpa + ent->len) {
> > +                /* remove partial extent */
> > +                uint64_t len1 = dpa - ent->start_dpa;
> > +                uint64_t len2 = ent->start_dpa + ent->len - dpa - len;
> > +
> > +                if (len1) {
> > +                    insert_extent_to_extent_list(extent_list, ent->start_dpa,
> > +                            len1, NULL, 0);
> > +                }
> > +                if (len2) {
> > +                    insert_extent_to_extent_list(extent_list, dpa + len, len2,
> > +                            NULL, 0);
> > +                }
> > +                break;
> > +            } else if ((dpa < ent->start_dpa + ent->len
> > +                        && dpa + len > ent->start_dpa + ent->len)
> > +                    || (dpa < ent->start_dpa && dpa + len > ent->start_dpa))
> > +                return CXL_MBOX_INVALID_EXTENT_LIST;
> > +        }
> > +
> > +        if (ent) {
> > +            QTAILQ_REMOVE(extent_list, ent, node);
> > +            g_free(ent);
> > +        } else {
> > +            /* Try to remove a non-existing extent */
> > +            return CXL_MBOX_INVALID_PA;
> > +        }
> > +    }
> > +
> > +    return CXL_MBOX_SUCCESS;
> > +}
> > +
> >   #define IMMEDIATE_CONFIG_CHANGE (1 << 1)
> >   #define IMMEDIATE_DATA_CHANGE (1 << 2)
> >   #define IMMEDIATE_POLICY_CHANGE (1 << 3)
> > @@ -1129,6 +1376,12 @@ static struct cxl_cmd cxl_cmd_set[256][256] = {
> >       [DCD_CONFIG][GET_DYN_CAP_EXT_LIST] = {
> >           "DCD_GET_DYNAMIC_CAPACITY_EXTENT_LIST", cmd_dcd_get_dyn_cap_ext_list,
> >           8, 0 },
> > +    [DCD_CONFIG][ADD_DYN_CAP_RSP] = {
> > +        "ADD_DCD_DYNAMIC_CAPACITY_RESPONSE", cmd_dcd_add_dyn_cap_rsp,
> > +        ~0, IMMEDIATE_DATA_CHANGE },
> > +    [DCD_CONFIG][RELEASE_DYN_CAP] = {
> > +        "RELEASE_DCD_DYNAMIC_CAPACITY", cmd_dcd_release_dyn_cap,
> > +        ~0, IMMEDIATE_DATA_CHANGE },
> >   };
> >
> >   static struct cxl_cmd cxl_cmd_set_sw[256][256] = {
> > diff --git a/include/hw/cxl/cxl_device.h b/include/hw/cxl/cxl_device.h
> > index 3a338b3b37..01a5eaca48 100644
> > --- a/include/hw/cxl/cxl_device.h
> > +++ b/include/hw/cxl/cxl_device.h
> > @@ -130,7 +130,8 @@ typedef enum {
> >       CXL_MBOX_INCORRECT_PASSPHRASE = 0x14,
> >       CXL_MBOX_UNSUPPORTED_MAILBOX = 0x15,
> >       CXL_MBOX_INVALID_PAYLOAD_LENGTH = 0x16,
> > -    CXL_MBOX_MAX = 0x17
> > +    CXL_MBOX_INVALID_EXTENT_LIST = 0x1E, /* cxl r3.0: Table 8-34*/
> > +    CXL_MBOX_MAX = 0x1F
> >   } CXLRetCode;
> >
> >   struct cxl_cmd;
> > --
> > 2.25.1

      reply	other threads:[~2023-09-08 17:21 UTC|newest]

Thread overview: 48+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <CGME20230725183956uscas1p154e945516c2a4091479f4906d7652648@uscas1p1.samsung.com>
2023-07-25 18:39 ` [Qemu PATCH v2 0/9] Enabling DCD emulation support in Qemu Fan Ni
2023-07-25 18:39   ` [Qemu PATCH v2 4/9] hw/mem/cxl_type3: Add support to create DC regions to type3 memory devices Fan Ni
2023-08-04 15:55     ` Jonathan Cameron
2023-08-04 15:55       ` Jonathan Cameron via
2023-07-25 18:39   ` [Qemu PATCH v2 3/9] include/hw/cxl/cxl_device: Rename mem_size as static_mem_size for " Fan Ni
2023-08-04 15:27     ` Jonathan Cameron
2023-08-04 15:27       ` Jonathan Cameron via
2023-07-25 18:39   ` [Qemu PATCH v2 2/9] hw/cxl/cxl-mailbox-utils: Add dynamic capacity region representative and mailbox command support Fan Ni
2023-08-04 15:24     ` Jonathan Cameron
2023-08-04 15:24       ` Jonathan Cameron via
2023-07-25 18:39   ` [Qemu PATCH v2 1/9] hw/cxl/cxl-mailbox-utils: Add dc_event_log_size field to output payload of identify memory device command Fan Ni
2023-08-04 14:19     ` Jonathan Cameron
2023-08-04 14:19       ` Jonathan Cameron via
2023-07-25 18:39   ` [Qemu PATCH v2 8/9] hw/cxl/events: Add qmp interfaces to add/release dynamic capacity extents Fan Ni
2023-08-07 10:35     ` Jonathan Cameron
2023-08-07 10:35       ` Jonathan Cameron via
2023-07-25 18:39   ` [Qemu PATCH v2 6/9] hw/mem/cxl_type3: Add DC extent list representative and get DC extent list mailbox support Fan Ni
2023-08-07 11:55     ` Jonathan Cameron
2023-08-07 11:55       ` Jonathan Cameron via
2023-09-08 13:12     ` Jørgen Hansen
2023-09-08 17:12       ` Fan Ni
2023-07-25 18:39   ` [Qemu PATCH v2 5/9] hw/mem/cxl_type3: Add host backend and address space handling for DC regions Fan Ni
2023-07-26 12:53     ` Nathan Fontenot
2023-07-26 16:17       ` nifan
2023-08-04 16:36     ` Jonathan Cameron
2023-08-04 16:36       ` Jonathan Cameron via
2023-08-04 18:07       ` Gregory Price
2023-08-07 12:10         ` Jonathan Cameron
2023-08-07 12:10           ` Jonathan Cameron via
2023-07-25 18:39   ` [Qemu PATCH v2 9/9] hw/mem/cxl_type3: Add dpa range validation for accesses to dc regions Fan Ni
2023-08-07  8:53     ` Jonathan Cameron
2023-08-07  8:53       ` Jonathan Cameron via
2023-08-07  9:37       ` Jonathan Cameron
2023-08-07  9:37         ` Jonathan Cameron via
2023-08-24 20:49       ` Fan Ni
2023-08-25 11:42         ` Jonathan Cameron
2023-08-25 11:42           ` Jonathan Cameron via
2023-08-25 16:34           ` Fan Ni
2023-08-30 15:04             ` Jonathan Cameron
2023-08-30 15:04               ` Jonathan Cameron via
2023-08-30 12:08     ` Jørgen Hansen
2023-08-30 15:37       ` Jonathan Cameron
2023-08-30 15:37         ` Jonathan Cameron via
2023-07-25 18:39   ` [Qemu PATCH v2 7/9] hw/cxl/cxl-mailbox-utils: Add mailbox commands to support add/release dynamic capacity response Fan Ni
2023-08-07 11:42     ` Jonathan Cameron
2023-08-07 11:42       ` Jonathan Cameron via
2023-09-08 13:00     ` Jørgen Hansen
2023-09-08 17:19       ` Fan Ni [this message]

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=ZPtXuyJkFKgBpL9A@debian \
    --to=fan.ni@gmx.us \
    --cc=Jorgen.Hansen@wdc.com \
    --cc=a.manzanares@samsung.com \
    --cc=cbrowy@avery-design.com \
    --cc=dan.j.williams@intel.com \
    --cc=dave@stgolabs.net \
    --cc=fan.ni@samsung.com \
    --cc=gregory.price@memverge.com \
    --cc=hchkuo@avery-design.com.tw \
    --cc=ira.weiny@intel.com \
    --cc=jonathan.cameron@huawei.com \
    --cc=linux-cxl@vger.kernel.org \
    --cc=nifan@outlook.com \
    --cc=nmtadam.samsung@gmail.com \
    --cc=qemu-devel@nongnu.org \
    /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.