All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jonathan Cameron <Jonathan.Cameron@Huawei.com>
To: Ira Weiny <ira.weiny@intel.com>
Cc: qemu-devel@nongnu.org, "Michael Tsirkin" <mst@redhat.com>,
	"Fan Ni" <fan.ni@samsung.com>,
	linux-cxl@vger.kernel.org, linuxarm@huawei.com,
	"Alison Schofield" <alison.schofield@intel.com>,
	"Michael Roth" <michael.roth@amd.com>,
	"Philippe Mathieu-Daudé" <philmd@linaro.org>,
	"Dave Jiang" <dave.jiang@intel.com>,
	"Markus Armbruster" <armbru@redhat.com>,
	"Daniel P . Berrangé" <berrange@redhat.com>,
	"Eric Blake" <eblake@redhat.com>,
	"Mike Maslenkin" <mike.maslenkin@gmail.com>,
	"Marc-André Lureau" <marcandre.lureau@redhat.com>,
	"Thomas Huth" <thuth@redhat.com>
Subject: Re: [PATCH v4 6/6] hw/cxl: Add clear poison mailbox command support.
Date: Mon, 6 Mar 2023 10:03:52 +0000	[thread overview]
Message-ID: <20230306100352.00004a51@Huawei.com> (raw)
In-Reply-To: <6402e9787cad0_606a629499@iweiny-mobl.notmuch>

On Fri, 3 Mar 2023 22:47:20 -0800
Ira Weiny <ira.weiny@intel.com> wrote:

> Jonathan Cameron wrote:
> > Current implementation is very simple so many of the corner
> > cases do not exist (e.g. fragmenting larger poison list entries)  
> 
> One coding style change at the bottom and I'm still hung up on that loop
> logic...
> 
> > 
> > Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
> > ---
> > v4:
> > - Fix off by one on check of edge of vmr (cut and paste from similar
> >   but long fixed in the volatile memory series)
> > - Drop unnecessary overflow check.
> > - Ensure that even in case of overflow we still delete the element
> >   replaced (in the hole punching case)
> > ---
> >  hw/cxl/cxl-mailbox-utils.c  | 77 +++++++++++++++++++++++++++++++++++++
> >  hw/mem/cxl_type3.c          | 36 +++++++++++++++++
> >  include/hw/cxl/cxl_device.h |  1 +
> >  3 files changed, 114 insertions(+)
> > 
> > diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c
> > index 64a3f3c1bf..0b30307fa3 100644
> > --- a/hw/cxl/cxl-mailbox-utils.c
> > +++ b/hw/cxl/cxl-mailbox-utils.c
> > @@ -65,6 +65,7 @@ enum {
> >      MEDIA_AND_POISON = 0x43,
> >          #define GET_POISON_LIST        0x0
> >          #define INJECT_POISON          0x1
> > +        #define CLEAR_POISON           0x2
> >  };
> >  
> >  /* 8.2.8.4.5.1 Command Return Codes */
> > @@ -511,6 +512,80 @@ static CXLRetCode cmd_media_inject_poison(struct cxl_cmd *cmd,
> >      return CXL_MBOX_SUCCESS;
> >  }
> >  
> > +static CXLRetCode cmd_media_clear_poison(struct cxl_cmd *cmd,
> > +                                         CXLDeviceState *cxl_dstate,
> > +                                         uint16_t *len)
> > +{
> > +    CXLType3Dev *ct3d = container_of(cxl_dstate, CXLType3Dev, cxl_dstate);
> > +    CXLPoisonList *poison_list = &ct3d->poison_list;
> > +    CXLType3Class *cvc = CXL_TYPE3_GET_CLASS(ct3d);
> > +    struct clear_poison_pl {
> > +        uint64_t dpa;
> > +        uint8_t data[64];
> > +    };
> > +    CXLPoison *ent;
> > +    uint64_t dpa;
> > +
> > +    struct clear_poison_pl *in = (void *)cmd->payload;
> > +
> > +    dpa = ldq_le_p(&in->dpa);
> > +    if (dpa + 64 > cxl_dstate->mem_size) {
> > +        return CXL_MBOX_INVALID_PA;
> > +    }
> > +
> > +    /* Always exit loop on entry removal so no need for safe variant */  
> 
> Commenting this is nice but I don't think it is needed.
> 
> > +    QLIST_FOREACH(ent, poison_list, node) {
> > +        /*
> > +         * Test for contained in entry. Simpler than general case
> > +         * as clearing 64 bytes and entries 64 byte aligned
> > +         */
> > +        if ((dpa < ent->start) || (dpa >= ent->start + ent->length)) {
> > +            continue;
> > +        }
> > +        /* Do accounting early as we know one will go away */
> > +        ct3d->poison_list_cnt--;  
> 
> Sorry to get so hung up on this but while I think this code now works I
> still think it is odd and will be an issue to maintain.
> 
> FWIW I don't think we have to keep 'ent' in the list here...
> 
> > +        if (dpa > ent->start) {
> > +            CXLPoison *frag;
> > +            /* Cannot overflow as replacing existing entry */
> > +
> > +            frag = g_new0(CXLPoison, 1);
> > +
> > +            frag->start = ent->start;
> > +            frag->length = dpa - ent->start;
> > +            frag->type = ent->type;
> > +
> > +            QLIST_INSERT_HEAD(poison_list, frag, node);
> > +            ct3d->poison_list_cnt++;
> > +        }
> > +        if (dpa + 64 < ent->start + ent->length) {
> > +            CXLPoison *frag;
> > +
> > +            if (ct3d->poison_list_cnt == CXL_POISON_LIST_LIMIT) {
> > +                cxl_set_poison_list_overflowed(ct3d);
> > +            } else {
> > +                frag = g_new0(CXLPoison, 1);
> > +
> > +                frag->start = dpa + 64;
> > +                frag->length = ent->start + ent->length - frag->start;
> > +                frag->type = ent->type;
> > +                QLIST_INSERT_HEAD(poison_list, frag, node);
> > +                ct3d->poison_list_cnt++;
> > +            }
> > +        }
> > +        /* Any fragments have been added, free original entry */
> > +        QLIST_REMOVE(ent, node);
> > +        g_free(ent);
> > +        break;
> > +    }  
> 
> Why not this?

Fair enough.  I think this is a case of code evolving to a state
that is non optimal in the end so I'll refactor it to something like
you have suggested.

I think we caan simplify it further by dragging the cacheline clear
up to before the list manipulation.

> 
> ...
>     CXLPoison *ent, found = NULL;
> 
> ...
>     QLIST_FOREACH(ent, poison_list, node) {
>         /*
>          * Test for contained in entry. Simpler than general case
>          * as clearing 64 bytes and entries are 64 byte aligned
>          */
>         if ((dpa >= ent->start) && (dpa < ent->start + ent->length)) {
>             found = ent;
> 	    break;
>         }
>     }
> 
>     /*
>      * Do we even need 'found'?  Or is ent null if not found?
>      * I'm not sure how QLIST's work.
>      */
>     if (found) {
>         CXLPoison *frag;
> 
>         QLIST_REMOVE(found, node);
>         ct3d->poison_list_cnt--;
> 
> 	/* If not clearing the start, create new beginning of range */
>         if (dpa > found->start) {
>             frag = g_new0(CXLPoison, 1);
>             frag->start = found->start;
>             frag->length = dpa - found->start;
>             frag->type = found->type;
>             QLIST_INSERT_HEAD(poison_list, frag, node);
>             ct3d->poison_list_cnt++;
> 	}
> 
> 	/* If needed, and space available, create new end of range */
>         if (dpa + 64 < found->start + found->length) {
>             if (ct3d->poison_list_cnt == CXL_POISON_LIST_LIMIT) {
>                 cxl_set_poison_list_overflowed(ct3d);
>             } else {
>                 frag = g_new0(CXLPoison, 1);
> 
>                 frag->start = dpa + 64;
>                 frag->length = found->start + found->length - frag->start;
>                 frag->type = found->type;
>                 QLIST_INSERT_HEAD(poison_list, frag, node);
>                 ct3d->poison_list_cnt++;
>             }
>         }
>         g_free(found);
>     }
> ...
> 
> > +    /* Clearing a region with no poison is not an error so always do so */
> > +    if (cvc->set_cacheline)  
> 
> For QEMU coding style you still need '{' '}'.
Gah.
> 
> Ira

Thanks,

Jonathan



WARNING: multiple messages have this Message-ID (diff)
From: Jonathan Cameron via <qemu-devel@nongnu.org>
To: Ira Weiny <ira.weiny@intel.com>
Cc: qemu-devel@nongnu.org, "Michael Tsirkin" <mst@redhat.com>,
	"Fan Ni" <fan.ni@samsung.com>,
	linux-cxl@vger.kernel.org, linuxarm@huawei.com,
	"Alison Schofield" <alison.schofield@intel.com>,
	"Michael Roth" <michael.roth@amd.com>,
	"Philippe Mathieu-Daudé" <philmd@linaro.org>,
	"Dave Jiang" <dave.jiang@intel.com>,
	"Markus Armbruster" <armbru@redhat.com>,
	"Daniel P . Berrangé" <berrange@redhat.com>,
	"Eric Blake" <eblake@redhat.com>,
	"Mike Maslenkin" <mike.maslenkin@gmail.com>,
	"Marc-André Lureau" <marcandre.lureau@redhat.com>,
	"Thomas Huth" <thuth@redhat.com>
Subject: Re: [PATCH v4 6/6] hw/cxl: Add clear poison mailbox command support.
Date: Mon, 6 Mar 2023 10:03:52 +0000	[thread overview]
Message-ID: <20230306100352.00004a51@Huawei.com> (raw)
In-Reply-To: <6402e9787cad0_606a629499@iweiny-mobl.notmuch>

On Fri, 3 Mar 2023 22:47:20 -0800
Ira Weiny <ira.weiny@intel.com> wrote:

> Jonathan Cameron wrote:
> > Current implementation is very simple so many of the corner
> > cases do not exist (e.g. fragmenting larger poison list entries)  
> 
> One coding style change at the bottom and I'm still hung up on that loop
> logic...
> 
> > 
> > Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
> > ---
> > v4:
> > - Fix off by one on check of edge of vmr (cut and paste from similar
> >   but long fixed in the volatile memory series)
> > - Drop unnecessary overflow check.
> > - Ensure that even in case of overflow we still delete the element
> >   replaced (in the hole punching case)
> > ---
> >  hw/cxl/cxl-mailbox-utils.c  | 77 +++++++++++++++++++++++++++++++++++++
> >  hw/mem/cxl_type3.c          | 36 +++++++++++++++++
> >  include/hw/cxl/cxl_device.h |  1 +
> >  3 files changed, 114 insertions(+)
> > 
> > diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c
> > index 64a3f3c1bf..0b30307fa3 100644
> > --- a/hw/cxl/cxl-mailbox-utils.c
> > +++ b/hw/cxl/cxl-mailbox-utils.c
> > @@ -65,6 +65,7 @@ enum {
> >      MEDIA_AND_POISON = 0x43,
> >          #define GET_POISON_LIST        0x0
> >          #define INJECT_POISON          0x1
> > +        #define CLEAR_POISON           0x2
> >  };
> >  
> >  /* 8.2.8.4.5.1 Command Return Codes */
> > @@ -511,6 +512,80 @@ static CXLRetCode cmd_media_inject_poison(struct cxl_cmd *cmd,
> >      return CXL_MBOX_SUCCESS;
> >  }
> >  
> > +static CXLRetCode cmd_media_clear_poison(struct cxl_cmd *cmd,
> > +                                         CXLDeviceState *cxl_dstate,
> > +                                         uint16_t *len)
> > +{
> > +    CXLType3Dev *ct3d = container_of(cxl_dstate, CXLType3Dev, cxl_dstate);
> > +    CXLPoisonList *poison_list = &ct3d->poison_list;
> > +    CXLType3Class *cvc = CXL_TYPE3_GET_CLASS(ct3d);
> > +    struct clear_poison_pl {
> > +        uint64_t dpa;
> > +        uint8_t data[64];
> > +    };
> > +    CXLPoison *ent;
> > +    uint64_t dpa;
> > +
> > +    struct clear_poison_pl *in = (void *)cmd->payload;
> > +
> > +    dpa = ldq_le_p(&in->dpa);
> > +    if (dpa + 64 > cxl_dstate->mem_size) {
> > +        return CXL_MBOX_INVALID_PA;
> > +    }
> > +
> > +    /* Always exit loop on entry removal so no need for safe variant */  
> 
> Commenting this is nice but I don't think it is needed.
> 
> > +    QLIST_FOREACH(ent, poison_list, node) {
> > +        /*
> > +         * Test for contained in entry. Simpler than general case
> > +         * as clearing 64 bytes and entries 64 byte aligned
> > +         */
> > +        if ((dpa < ent->start) || (dpa >= ent->start + ent->length)) {
> > +            continue;
> > +        }
> > +        /* Do accounting early as we know one will go away */
> > +        ct3d->poison_list_cnt--;  
> 
> Sorry to get so hung up on this but while I think this code now works I
> still think it is odd and will be an issue to maintain.
> 
> FWIW I don't think we have to keep 'ent' in the list here...
> 
> > +        if (dpa > ent->start) {
> > +            CXLPoison *frag;
> > +            /* Cannot overflow as replacing existing entry */
> > +
> > +            frag = g_new0(CXLPoison, 1);
> > +
> > +            frag->start = ent->start;
> > +            frag->length = dpa - ent->start;
> > +            frag->type = ent->type;
> > +
> > +            QLIST_INSERT_HEAD(poison_list, frag, node);
> > +            ct3d->poison_list_cnt++;
> > +        }
> > +        if (dpa + 64 < ent->start + ent->length) {
> > +            CXLPoison *frag;
> > +
> > +            if (ct3d->poison_list_cnt == CXL_POISON_LIST_LIMIT) {
> > +                cxl_set_poison_list_overflowed(ct3d);
> > +            } else {
> > +                frag = g_new0(CXLPoison, 1);
> > +
> > +                frag->start = dpa + 64;
> > +                frag->length = ent->start + ent->length - frag->start;
> > +                frag->type = ent->type;
> > +                QLIST_INSERT_HEAD(poison_list, frag, node);
> > +                ct3d->poison_list_cnt++;
> > +            }
> > +        }
> > +        /* Any fragments have been added, free original entry */
> > +        QLIST_REMOVE(ent, node);
> > +        g_free(ent);
> > +        break;
> > +    }  
> 
> Why not this?

Fair enough.  I think this is a case of code evolving to a state
that is non optimal in the end so I'll refactor it to something like
you have suggested.

I think we caan simplify it further by dragging the cacheline clear
up to before the list manipulation.

> 
> ...
>     CXLPoison *ent, found = NULL;
> 
> ...
>     QLIST_FOREACH(ent, poison_list, node) {
>         /*
>          * Test for contained in entry. Simpler than general case
>          * as clearing 64 bytes and entries are 64 byte aligned
>          */
>         if ((dpa >= ent->start) && (dpa < ent->start + ent->length)) {
>             found = ent;
> 	    break;
>         }
>     }
> 
>     /*
>      * Do we even need 'found'?  Or is ent null if not found?
>      * I'm not sure how QLIST's work.
>      */
>     if (found) {
>         CXLPoison *frag;
> 
>         QLIST_REMOVE(found, node);
>         ct3d->poison_list_cnt--;
> 
> 	/* If not clearing the start, create new beginning of range */
>         if (dpa > found->start) {
>             frag = g_new0(CXLPoison, 1);
>             frag->start = found->start;
>             frag->length = dpa - found->start;
>             frag->type = found->type;
>             QLIST_INSERT_HEAD(poison_list, frag, node);
>             ct3d->poison_list_cnt++;
> 	}
> 
> 	/* If needed, and space available, create new end of range */
>         if (dpa + 64 < found->start + found->length) {
>             if (ct3d->poison_list_cnt == CXL_POISON_LIST_LIMIT) {
>                 cxl_set_poison_list_overflowed(ct3d);
>             } else {
>                 frag = g_new0(CXLPoison, 1);
> 
>                 frag->start = dpa + 64;
>                 frag->length = found->start + found->length - frag->start;
>                 frag->type = found->type;
>                 QLIST_INSERT_HEAD(poison_list, frag, node);
>                 ct3d->poison_list_cnt++;
>             }
>         }
>         g_free(found);
>     }
> ...
> 
> > +    /* Clearing a region with no poison is not an error so always do so */
> > +    if (cvc->set_cacheline)  
> 
> For QEMU coding style you still need '{' '}'.
Gah.
> 
> Ira

Thanks,

Jonathan




  reply	other threads:[~2023-03-06 10:04 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-03-03 15:09 [PATCH v4 0/6] hw/cxl: Poison get, inject, clear Jonathan Cameron
2023-03-03 15:09 ` Jonathan Cameron via
2023-03-03 15:09 ` [PATCH v4 1/6] hw/cxl: rename mailbox return code type from ret_code to CXLRetCode Jonathan Cameron
2023-03-03 15:09   ` Jonathan Cameron via
2023-03-14  5:55   ` Philippe Mathieu-Daudé
2023-03-03 15:09 ` [PATCH v4 2/6] hw/cxl: Introduce cxl_device_get_timestamp() utility function Jonathan Cameron
2023-03-03 15:09   ` Jonathan Cameron via
2023-03-03 15:09 ` [PATCH v4 3/6] bswap: Add the ability to store to an unaligned 24 bit field Jonathan Cameron
2023-03-03 15:09   ` Jonathan Cameron via
2023-03-14  6:13   ` Philippe Mathieu-Daudé
2023-03-03 15:09 ` [PATCH v4 4/6] hw/cxl: QMP based poison injection support Jonathan Cameron
2023-03-03 15:09   ` Jonathan Cameron via
2023-03-03 21:21   ` Ira Weiny
2023-03-14  5:21   ` Fan Ni
2023-03-14  6:22   ` Philippe Mathieu-Daudé
2023-03-03 15:09 ` [PATCH v4 5/6] hw/cxl: Add poison injection via the mailbox Jonathan Cameron
2023-03-03 15:09   ` Jonathan Cameron via
2023-03-14  5:22   ` Fan Ni
2023-03-14  6:27   ` Philippe Mathieu-Daudé
2023-04-21 17:33     ` Jonathan Cameron
2023-04-21 17:33       ` Jonathan Cameron via
2023-03-03 15:09 ` [PATCH v4 6/6] hw/cxl: Add clear poison mailbox command support Jonathan Cameron
2023-03-03 15:09   ` Jonathan Cameron via
2023-03-04  6:47   ` Ira Weiny
2023-03-06 10:03     ` Jonathan Cameron [this message]
2023-03-06 10:03       ` Jonathan Cameron via
2023-03-13 16:16   ` Jonathan Cameron
2023-03-13 16:16     ` Jonathan Cameron via
2023-03-14  5:29   ` Fan Ni
2023-03-14  6:32 ` [PATCH v4 0/6] hw/cxl: Poison get, inject, clear Philippe Mathieu-Daudé

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=20230306100352.00004a51@Huawei.com \
    --to=jonathan.cameron@huawei.com \
    --cc=alison.schofield@intel.com \
    --cc=armbru@redhat.com \
    --cc=berrange@redhat.com \
    --cc=dave.jiang@intel.com \
    --cc=eblake@redhat.com \
    --cc=fan.ni@samsung.com \
    --cc=ira.weiny@intel.com \
    --cc=linux-cxl@vger.kernel.org \
    --cc=linuxarm@huawei.com \
    --cc=marcandre.lureau@redhat.com \
    --cc=michael.roth@amd.com \
    --cc=mike.maslenkin@gmail.com \
    --cc=mst@redhat.com \
    --cc=philmd@linaro.org \
    --cc=qemu-devel@nongnu.org \
    --cc=thuth@redhat.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.