From: Ira Weiny <ira.weiny@intel.com>
To: Alison Schofield <alison.schofield@intel.com>, <ira.weiny@intel.com>
Cc: Navneet Singh <navneet.singh@intel.com>,
Fan Ni <fan.ni@samsung.com>,
Jonathan Cameron <Jonathan.Cameron@huawei.com>,
Dan Williams <dan.j.williams@intel.com>,
<linux-cxl@vger.kernel.org>
Subject: Re: [PATCH 2/5] cxl/region: Add dynamic capacity cxl region support.
Date: Tue, 20 Jun 2023 19:44:15 -0700 [thread overview]
Message-ID: <649263ff75fcc_483a294d9@iweiny-mobl.notmuch> (raw)
In-Reply-To: <ZIyTFpniGlEv2QEo@aschofie-mobl2>
Alison Schofield wrote:
> On Wed, Jun 14, 2023 at 12:16:29PM -0700, Ira Weiny wrote:
> > From: Navneet Singh <navneet.singh@intel.com>
> >
> > CXL devices optionally support dynamic capacity. CXL Regions must be
> > created to access this capacity.
> >
> > Add sysfs entries to create dynamic capacity cxl regions. Provide a new
> > Dynamic Capacity decoder mode which targets dynamic capacity on devices
> > which are added to that region.
> >
> > Below are the steps to create and delete dynamic capacity region0
> > (example).
> >
> > region=$(cat /sys/bus/cxl/devices/decoder0.0/create_dc_region)
> > echo $region> /sys/bus/cxl/devices/decoder0.0/create_dc_region
> > echo 256 > /sys/bus/cxl/devices/$region/interleave_granularity
> > echo 1 > /sys/bus/cxl/devices/$region/interleave_ways
> >
> > echo "dc0" >/sys/bus/cxl/devices/decoder1.0/mode
> > echo 0x400000000 >/sys/bus/cxl/devices/decoder1.0/dpa_size
> >
> > echo 0x400000000 > /sys/bus/cxl/devices/$region/size
> > echo "decoder1.0" > /sys/bus/cxl/devices/$region/target0
> > echo 1 > /sys/bus/cxl/devices/$region/commit
> > echo $region > /sys/bus/cxl/drivers/cxl_region/bind
> >
> > echo $region> /sys/bus/cxl/devices/decoder0.0/delete_region
> >
> > Signed-off-by: Navneet Singh <navneet.singh@intel.com>
>
> Hi,
> I took another pass at this and offered more feedback.
> I do think that if the big part - the cxl_dpa_reserve()
> was more 'chunkified' it would be easier to review for
> actual functionality.
>
> I'd also like to see the commit log be a bit more specific
> in enumerated the things this patch intends to do.
>
> Many of my comments are about style. Some checkpatch --strict
> would call out and some are addressed in the kernel coding
> style - Documentation/process/coding-style.rst
As I said before I did not run with --strict
I've done a quick run through with --strict and will ensure it is done
again after I refactor the code.
>
> But really, my goal is that when this code merges, that as
> I scroll through a file, say region.c, I see a consistent
> coding style. I shouldn't be able to notice that oh, Dan
> wrote that, and Ira that, and Navneet wrote that piece.
I agree.
>
> I think it's important because differences in style distract
> from focusing on the functionality of the code.
>
> (off my soap box now ;)
>
> Alison
>
>
> >
> > ---
> > [iweiny: fixups]
> > [iweiny: remove unused CXL_DC_REGION_MODE macro]
> > [iweiny: Make dc_mode_to_region_index static]
> > [iweiny: simplify <sysfs>/create_dc_region]
> > [iweiny: introduce decoder_mode_is_dc]
> > [djbw: fixups, no sign-off: preview only]
> > ---
> > drivers/cxl/Kconfig | 11 +++
> > drivers/cxl/core/core.h | 7 ++
> > drivers/cxl/core/hdm.c | 234 ++++++++++++++++++++++++++++++++++++++++++----
> > drivers/cxl/core/port.c | 18 ++++
> > drivers/cxl/core/region.c | 135 ++++++++++++++++++++++++--
> > drivers/cxl/cxl.h | 28 ++++++
> > drivers/dax/cxl.c | 4 +
> > 7 files changed, 409 insertions(+), 28 deletions(-)
> >
> > diff --git a/drivers/cxl/Kconfig b/drivers/cxl/Kconfig
> > index ff4e78117b31..df034889d053 100644
> > --- a/drivers/cxl/Kconfig
> > +++ b/drivers/cxl/Kconfig
> > @@ -121,6 +121,17 @@ config CXL_REGION
> >
> > If unsure say 'y'
> >
> > +config CXL_DCD
> > + bool "CXL: DCD Support"
>
> "CXL DCD: Dynamic Capacity Device Support"
> is more in line with others in this file, and expands the acronym onetime.
done.
>
> > + default CXL_BUS
> > + depends on CXL_REGION
> > + help
> > + Enable the CXL core to provision CXL DCD regions.
> > + CXL devices optionally support dynamic capacity and DCD region
> > + maps the dynamic capacity regions DPA's into Host HPA ranges.
> > +
> > + If unsure say 'y'
> > +
> > config CXL_REGION_INVALIDATION_TEST
> > bool "CXL: Region Cache Management Bypass (TEST)"
> > depends on CXL_REGION
> > diff --git a/drivers/cxl/core/core.h b/drivers/cxl/core/core.h
> > index 27f0968449de..725700ab5973 100644
> > --- a/drivers/cxl/core/core.h
> > +++ b/drivers/cxl/core/core.h
> > @@ -9,6 +9,13 @@ extern const struct device_type cxl_nvdimm_type;
> >
> > extern struct attribute_group cxl_base_attribute_group;
> >
> > +#ifdef CONFIG_CXL_DCD
> > +extern struct device_attribute dev_attr_create_dc_region;
> > +#define SET_CXL_DC_REGION_ATTR(x) (&dev_attr_##x.attr),
> > +#else
> > +#define SET_CXL_DC_REGION_ATTR(x)
> > +#endif
> > +
> > #ifdef CONFIG_CXL_REGION
> > extern struct device_attribute dev_attr_create_pmem_region;
> > extern struct device_attribute dev_attr_create_ram_region;
> > diff --git a/drivers/cxl/core/hdm.c b/drivers/cxl/core/hdm.c
> > index 514d30131d92..29649b47d177 100644
> > --- a/drivers/cxl/core/hdm.c
> > +++ b/drivers/cxl/core/hdm.c
> > @@ -233,14 +233,23 @@ static void __cxl_dpa_release(struct cxl_endpoint_decoder *cxled)
> > struct cxl_dev_state *cxlds = cxlmd->cxlds;
> > struct resource *res = cxled->dpa_res;
> > resource_size_t skip_start;
> > + resource_size_t skipped = cxled->skip;
>
> Reverse x-tree.
Done.
>
> >
> > lockdep_assert_held_write(&cxl_dpa_rwsem);
> >
> > /* save @skip_start, before @res is released */
> > - skip_start = res->start - cxled->skip;
> > + skip_start = res->start - skipped;
>
> Why did the assignment of skip_start need to change here?
I believe this was done for consistency because skipped now represents
cxled->skip, however...
>
> > __release_region(&cxlds->dpa_res, res->start, resource_size(res));
> > - if (cxled->skip)
> > - __release_region(&cxlds->dpa_res, skip_start, cxled->skip);
> > + if (cxled->skip != 0) {
> > + while (skipped != 0) {
... what is more concerning is we now effectively have.
if (skipped != 0) {
while (skipped != 0) {
...
:-(
> > + res = xa_load(&cxled->skip_res, skip_start);
> > + __release_region(&cxlds->dpa_res, skip_start,
> > + resource_size(res));
>
> The above appears poorlty aligned.
fixed.
>
> > + xa_erase(&cxled->skip_res, skip_start);
> > + skip_start += resource_size(res);
> > + skipped -= resource_size(res);
> > + }
>
> This bracket appears poorly aligned.
This is very poorly aligned. I'll run --strict before sending V2.
>
> > + }
> > cxled->skip = 0;
> > cxled->dpa_res = NULL;
> > put_device(&cxled->cxld.dev);
> > @@ -267,6 +276,19 @@ static void devm_cxl_dpa_release(struct cxl_endpoint_decoder *cxled)
> > __cxl_dpa_release(cxled);
> > }
> >
> > +static int dc_mode_to_region_index(enum cxl_decoder_mode mode)
> > +{
> > + int index = 0;
> > +
> > + for (int i = CXL_DECODER_DC0; i <= CXL_DECODER_DC7; i++) {
> > + if (mode == i)
> > + return index;
> > + index++;
> > + }
> > +
> > + return -EINVAL;
> > +}
> > +
> > static int __cxl_dpa_reserve(struct cxl_endpoint_decoder *cxled,
> > resource_size_t base, resource_size_t len,
> > resource_size_t skipped)
> > @@ -275,7 +297,11 @@ static int __cxl_dpa_reserve(struct cxl_endpoint_decoder *cxled,
> > struct cxl_port *port = cxled_to_port(cxled);
> > struct cxl_dev_state *cxlds = cxlmd->cxlds;
> > struct device *dev = &port->dev;
> > + struct device *ed_dev = &cxled->cxld.dev;
> > + struct resource *dpa_res = &cxlds->dpa_res;
> > + resource_size_t skip_len = 0;
> > struct resource *res;
> > + int rc, index;
> >
>
> Above poorly aligned.
Do you mean reverse x-tree?
>
> > lockdep_assert_held_write(&cxl_dpa_rwsem);
> >
> > @@ -304,28 +330,119 @@ static int __cxl_dpa_reserve(struct cxl_endpoint_decoder *cxled,
> > }
> >
> > if (skipped) {
>
> This has excessive indentation, so started out with a monster
> if skipped is begging for a refactoring.
Yea I agree. Dave pointed this out as well. What I have to be sure about
is the logic here.
>
> I find it odd that the DCD case got inserted before the 'default'
> or non-DCD case here.
Yea I'm working with Navneet on this.
>
>
> > - res = __request_region(&cxlds->dpa_res, base - skipped, skipped,
> > - dev_name(&cxled->cxld.dev), 0);
> > - if (!res) {
> > - dev_dbg(dev,
> > - "decoder%d.%d: failed to reserve skipped space\n",
> > - port->id, cxled->cxld.id);
> > - return -EBUSY;
> > + resource_size_t skip_base = base - skipped;
> > +
> > + if (decoder_mode_is_dc(cxled->mode)) {
>
> This may be cleaner to introduce as a separate function for
> handling _mode_id_dc.
Yes I think all the DC in this function should be handled in it's own
function to clarify how that is handled.
I think it will make the diff/review easier as well because it will be
more clear how things are with and without DCD.
>
> > + if (resource_size(&cxlds->ram_res) &&
> > + skip_base <= cxlds->ram_res.end) {
> > + skip_len = cxlds->ram_res.end - skip_base + 1;
> > + res = __request_region(dpa_res, skip_base,
> > + skip_len, dev_name(ed_dev), 0);
> > + if (!res)
> > + goto error;
> > +
> > + rc = xa_insert(&cxled->skip_res, skip_base, res,
> > + GFP_KERNEL);
> > + skip_base += skip_len;
> > + }
> > +
> > + if (resource_size(&cxlds->ram_res) &&
> > + skip_base <= cxlds->pmem_res.end) {
> > + skip_len = cxlds->pmem_res.end - skip_base + 1;
> > + res = __request_region(dpa_res, skip_base,
> > + skip_len, dev_name(ed_dev), 0);
> > + if (!res)
> > + goto error;
> > +
> > + rc = xa_insert(&cxled->skip_res, skip_base, res,
> > + GFP_KERNEL);
> > + skip_base += skip_len;
> > + }
>
> The above 2 if (resource_size() cases have redundant code.
> Pull it out, refactor.
Redundant except that the second ram_res needs to be pmem_res. After
that change I'll have to evaluate how much is duplicated. As I said above
I'm working with Navneet to see how this logic can be broken down. It is
a big function now.
>
> > +
> > + index = dc_mode_to_region_index(cxled->mode);
> > + for (int i = 0; i <= index; i++) {
> > + struct resource *dcr = &cxlds->dc_res[i];
> > +
> > + if (skip_base < dcr->start) {
> > + skip_len = dcr->start - skip_base;
> > + res = __request_region(dpa_res,
> > + skip_base, skip_len,
> > + dev_name(ed_dev), 0);
> > + if (!res)
> > + goto error;
> > +
> > + rc = xa_insert(&cxled->skip_res, skip_base,
> > + res, GFP_KERNEL);
> > + skip_base += skip_len;
> > + }
> > +
> > + if (skip_base == base) {
> > + dev_dbg(dev, "skip done!\n");
> > + break;
> > + }
> > +
> > + if (resource_size(dcr) &&
> > + skip_base <= dcr->end) {
> > + if (skip_base > base)
> > + dev_err(dev, "Skip error\n");
> > +
> > + skip_len = dcr->end - skip_base + 1;
> > + res = __request_region(dpa_res, skip_base,
> > + skip_len,
> > + dev_name(ed_dev), 0);
> > + if (!res)
> > + goto error;
> > +
> > + rc = xa_insert(&cxled->skip_res, skip_base,
> > + res, GFP_KERNEL);
> > + skip_base += skip_len;
> > + }
> > + }
>
>
> And, below,we are back to the original code.
> This would be more readable, reviewable if the DCD support was
> added in separate function that are then called from here.
Yep!
>
> > + } else {
> > + res = __request_region(dpa_res, base - skipped, skipped,
> > + dev_name(ed_dev), 0);
> > + if (!res)
> > + goto error;
> > +
> > + rc = xa_insert(&cxled->skip_res, skip_base, res,
> > + GFP_KERNEL);
> > }
> > }
> > - res = __request_region(&cxlds->dpa_res, base, len,
> > - dev_name(&cxled->cxld.dev), 0);
> > +
> > + res = __request_region(dpa_res, base, len, dev_name(ed_dev), 0);
> > if (!res) {
> > dev_dbg(dev, "decoder%d.%d: failed to reserve allocation\n",
> > - port->id, cxled->cxld.id);
>
> General comment - look over the dev_dbg() messages and consider placing
> them after the code. I recall, others that were needlessly between lines
> of code.
At the end of the block?
>
>
> > - if (skipped)
> > - __release_region(&cxlds->dpa_res, base - skipped,
> > - skipped);
> > + port->id, cxled->cxld.id);
> > + if (skipped) {
> > + resource_size_t skip_base = base - skipped;
> > +
> > + while (skipped != 0) {
> > + if (skip_base > base)
> > + dev_err(dev, "Skip error\n");
> > +
> > + res = xa_load(&cxled->skip_res, skip_base);
> > + __release_region(dpa_res, skip_base,
> > + resource_size(res));
> > + xa_erase(&cxled->skip_res, skip_base);
> > + skip_base += resource_size(res);
> > + skipped -= resource_size(res);
> > + }
> > + }
>
> Can that debug message go here ?
Not sure. But we have another issue of:
if (skipped) {
while (skipped) {
...
which is redundant I think. I'll have to see about skip_base.
>
> > return -EBUSY;
> > }
> > cxled->dpa_res = res;
> > cxled->skip = skipped;
> >
> > + for (int mode = CXL_DECODER_DC0; mode <= CXL_DECODER_DC7; mode++) {
> > + int index = dc_mode_to_region_index(mode);
> > +
> > + if (resource_contains(&cxlds->dc_res[index], res)) {
> > + cxled->mode = mode;
> > + dev_dbg(dev, "decoder%d.%d: %pr mode: %d\n", port->id,
> > + cxled->cxld.id, cxled->dpa_res, cxled->mode);
>
> Can this move to ....
>
>
> > + goto success;
> > + }
> > + }
> > if (resource_contains(&cxlds->pmem_res, res))
> > cxled->mode = CXL_DECODER_PMEM;
> > else if (resource_contains(&cxlds->ram_res, res))
> > @@ -336,9 +453,16 @@ static int __cxl_dpa_reserve(struct cxl_endpoint_decoder *cxled,
> > cxled->mode = CXL_DECODER_MIXED;
> > }
> >
> > +success:
> > port->hdm_end++;
> > get_device(&cxled->cxld.dev);
>
> here...dev_dbg() success message. That pairs it nicely with the
> error message below.
I think it can. I think we have a case here where there was an attempt
not to change the initial behavior of the code even so much as adding a
debug message. But I think the over all flow would be better with the
debug here.
>
> > return 0;
> > +
> > +error:
> > + dev_dbg(dev, "decoder%d.%d: failed to reserve skipped space\n",
> > + port->id, cxled->cxld.id);
> > + return -EBUSY;
> > +
> > }
> >
> > int devm_cxl_dpa_reserve(struct cxl_endpoint_decoder *cxled,
> > @@ -429,6 +553,14 @@ int cxl_dpa_set_mode(struct cxl_endpoint_decoder *cxled,
> > switch (mode) {
> > case CXL_DECODER_RAM:
> > case CXL_DECODER_PMEM:
> > + case CXL_DECODER_DC0:
> > + case CXL_DECODER_DC1:
> > + case CXL_DECODER_DC2:
> > + case CXL_DECODER_DC3:
> > + case CXL_DECODER_DC4:
> > + case CXL_DECODER_DC5:
> > + case CXL_DECODER_DC6:
> > + case CXL_DECODER_DC7:
> > break;
> > default:
> > dev_dbg(dev, "unsupported mode: %d\n", mode);
> > @@ -456,6 +588,16 @@ int cxl_dpa_set_mode(struct cxl_endpoint_decoder *cxled,
> > goto out;
> > }
> >
> > + for (int i = CXL_DECODER_DC0; i <= CXL_DECODER_DC7; i++) {
> > + int index = dc_mode_to_region_index(i);
> > +
> > + if (mode == i && !resource_size(&cxlds->dc_res[index])) {
> > + dev_dbg(dev, "no available dynamic capacity\n");
>
> I see this one is following the pattern in the function :)
>
>
> > + rc = -ENXIO;
> > + goto out;
> > + }
> > + }
> > +
> > cxled->mode = mode;
> > rc = 0;
> > out:
> > @@ -469,10 +611,12 @@ static resource_size_t cxl_dpa_freespace(struct cxl_endpoint_decoder *cxled,
>
> Hmmm...I don't have cxl_dpa_freespace() in my cxl/next? Where's that?
That was in the patches from Dan which this series depends on.
https://lore.kernel.org/all/168592158743.1948938.7622563891193802610.stgit@dwillia2-xfh.jf.intel.com/
>
>
> > resource_size_t *skip_out)
> > {
> > struct cxl_memdev *cxlmd = cxled_to_memdev(cxled);
> > - resource_size_t free_ram_start, free_pmem_start;
> > + resource_size_t free_ram_start, free_pmem_start, free_dc_start;
> > struct cxl_dev_state *cxlds = cxlmd->cxlds;
> > + struct device *dev = &cxled->cxld.dev;
> > resource_size_t start, avail, skip;
> > struct resource *p, *last;
> > + int index;
>
> Why break the alignment above?
What do you mean?
>
> >
> > lockdep_assert_held(&cxl_dpa_rwsem);
> >
> > @@ -490,6 +634,20 @@ static resource_size_t cxl_dpa_freespace(struct cxl_endpoint_decoder *cxled,
> > else
> > free_pmem_start = cxlds->pmem_res.start;
> >
> > + /*
> > + * One HDM Decoder per DC region to map memory with different
> > + * DSMAS entry.
> > + */
>
> It seems this comment is missing a verb. Why not align?
align?
with DSMAS on the end like this?
/*
* One HDM Decoder per DC region to map memory with different DSMAS
* entry.
*/
> > + index = dc_mode_to_region_index(cxled->mode);
> > + if (index >= 0) {
> > + if (cxlds->dc_res[index].child) {
> > + dev_err(dev, "Cannot allocated DPA from DC Region: %d\n"
>
> s/allocated/allocate
Fixed.
>
> ,
> > + index);
> > + return -EINVAL;
> > + }
> > + free_dc_start = cxlds->dc_res[index].start;
> > + }
> > +
> > if (cxled->mode == CXL_DECODER_RAM) {
> > start = free_ram_start;
> > avail = cxlds->ram_res.end - start + 1;
> > @@ -511,6 +669,29 @@ static resource_size_t cxl_dpa_freespace(struct cxl_endpoint_decoder *cxled,
> > else
> > skip_end = start - 1;
> > skip = skip_end - skip_start + 1;
> > + } else if (decoder_mode_is_dc(cxled->mode)) {
> > + resource_size_t skip_start, skip_end;
> > +
> > + start = free_dc_start;
> > + avail = cxlds->dc_res[index].end - start + 1;
> > + if ((resource_size(&cxlds->pmem_res) == 0) || !cxlds->pmem_res.child)
> > + skip_start = free_ram_start;
> > + else
> > + skip_start = free_pmem_start;
> > + /*
> > + * If some dc region is already mapped, then that allocation
>
> maybe s/some/any ?
Fixed.
Ira
next prev parent reply other threads:[~2023-06-21 2:44 UTC|newest]
Thread overview: 55+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-06-14 19:16 [PATCH 0/5] cxl/dcd: Add support for Dynamic Capacity Devices (DCD) ira.weiny
2023-06-14 19:16 ` [PATCH 1/5] cxl/mem : Read Dynamic capacity configuration from the device ira.weiny
2023-06-14 22:53 ` Dave Jiang
2023-06-15 15:04 ` Ira Weiny
2023-06-14 23:49 ` Alison Schofield
2023-06-15 22:46 ` Ira Weiny
2023-06-15 18:30 ` Fan Ni
2023-06-15 19:17 ` Navneet Singh
2023-06-15 21:41 ` Fan Ni
2023-06-22 15:58 ` Jonathan Cameron
2023-06-24 13:08 ` Ira Weiny
2023-07-03 2:29 ` Jonathan Cameron
2023-06-14 19:16 ` [PATCH 2/5] cxl/region: Add dynamic capacity cxl region support ira.weiny
2023-06-14 23:37 ` Dave Jiang
2023-06-15 18:12 ` Ira Weiny
2023-06-15 18:28 ` Dave Jiang
2023-06-16 3:52 ` Navneet Singh
2023-06-15 18:56 ` Navneet Singh
2023-06-15 0:21 ` Alison Schofield
2023-06-16 2:06 ` Ira Weiny
2023-06-16 15:56 ` Alison Schofield
2023-06-16 16:51 ` Alison Schofield
2023-06-21 2:44 ` Ira Weiny [this message]
2023-06-20 17:55 ` Fan Ni
2023-06-20 20:33 ` Ira Weiny
2023-06-21 3:13 ` Navneet Singh
2023-06-21 17:20 ` Fan Ni
2023-06-23 18:02 ` Ira Weiny
2023-06-22 16:34 ` Jonathan Cameron
2023-07-05 14:49 ` Davidlohr Bueso
2023-06-14 19:16 ` [PATCH 3/5] cxl/mem : Expose dynamic capacity configuration to userspace ira.weiny
2023-06-15 0:40 ` Alison Schofield
2023-06-16 2:47 ` Ira Weiny
2023-06-16 15:58 ` Dave Jiang
2023-06-20 16:23 ` Ira Weiny
2023-06-20 16:48 ` Dave Jiang
2023-06-15 15:41 ` Dave Jiang
2023-06-14 19:16 ` [PATCH 4/5] cxl/mem: Add support to handle DCD add and release capacity events ira.weiny
2023-06-15 2:19 ` Alison Schofield
2023-06-16 4:11 ` Ira Weiny
2023-06-27 18:20 ` Fan Ni
2023-06-15 16:58 ` Dave Jiang
2023-06-22 17:01 ` Jonathan Cameron
2023-06-29 15:19 ` Ira Weiny
2023-06-27 18:17 ` Fan Ni
2023-07-13 12:55 ` Jørgen Hansen
2023-06-14 19:16 ` [PATCH 5/5] cxl/mem: Trace Dynamic capacity Event Record ira.weiny
2023-06-15 17:08 ` Dave Jiang
2023-06-15 0:56 ` [PATCH 0/5] cxl/dcd: Add support for Dynamic Capacity Devices (DCD) Alison Schofield
2023-06-16 2:57 ` Ira Weiny
2023-06-15 14:51 ` Ira Weiny
2023-06-22 15:07 ` Jonathan Cameron
2023-06-22 16:37 ` Jonathan Cameron
2023-06-27 14:59 ` Ira Weiny
2023-06-29 15:30 ` Ira Weiny
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=649263ff75fcc_483a294d9@iweiny-mobl.notmuch \
--to=ira.weiny@intel.com \
--cc=Jonathan.Cameron@huawei.com \
--cc=alison.schofield@intel.com \
--cc=dan.j.williams@intel.com \
--cc=fan.ni@samsung.com \
--cc=linux-cxl@vger.kernel.org \
--cc=navneet.singh@intel.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.