From: Ira Weiny <ira.weiny@intel.com>
To: Alison Schofield <alison.schofield@intel.com>
Cc: Vishal Verma <vishal.l.verma@intel.com>,
Jonathan Cameron <jonathan.cameron@Huawei.com>,
Fan Ni <fan.ni@samsung.com>,
Sushant1 Kumar <sushant1.kumar@intel.com>,
Dan Williams <dan.j.williams@intel.com>,
Dave Jiang <dave.jiang@intel.com>,
linux-cxl@vger.kernel.org, nvdimm@lists.linux.dev,
Ira Weiny <ira.weiny@intel.com>
Subject: [ndctl PATCH v4 5/9] libcxl: Add Dynamic Capacity region support
Date: Sat, 14 Dec 2024 20:58:32 -0600 [thread overview]
Message-ID: <20241214-dcd-region2-v4-5-36550a97f8e2@intel.com> (raw)
In-Reply-To: <20241214-dcd-region2-v4-0-36550a97f8e2@intel.com>
CXL Dynamic Capacity Devices (DCDs) optionally support dynamic capacity
with up to eight partitions (Regions) (dc0-dc7). CXL regions can now be
sparse and defined as dynamic capacity (dc).
Add support for DCD devices and regions to libcxl. Add documentation
for the new interfaces.
Based on an original patch from Navneet Singh.
Signed-off-by: Sushant1 Kumar <sushant1.kumar@intel.com>
Co-developed-by: Ira Weiny <ira.weiny@intel.com>
Signed-off-by: Ira Weiny <ira.weiny@intel.com>
---
Documentation/cxl/lib/libcxl.txt | 17 ++++++-
cxl/lib/libcxl.c | 98 ++++++++++++++++++++++++++++++++++++++++
cxl/lib/libcxl.sym | 3 ++
cxl/lib/private.h | 4 ++
cxl/libcxl.h | 52 ++++++++++++++++++++-
5 files changed, 171 insertions(+), 3 deletions(-)
diff --git a/Documentation/cxl/lib/libcxl.txt b/Documentation/cxl/lib/libcxl.txt
index d5c3558aacecb08d7f5754fdcc77d6e743560601..abca08fc81e6e84d176facafad6decae2f875880 100644
--- a/Documentation/cxl/lib/libcxl.txt
+++ b/Documentation/cxl/lib/libcxl.txt
@@ -68,6 +68,7 @@ int cxl_memdev_get_major(struct cxl_memdev *memdev);
int cxl_memdev_get_minor(struct cxl_memdev *memdev);
unsigned long long cxl_memdev_get_pmem_size(struct cxl_memdev *memdev);
unsigned long long cxl_memdev_get_ram_size(struct cxl_memdev *memdev);
+unsigned long long cxl_memdev_get_dc_size(struct cxl_memdev *memdev, enum cxl_decoder_mode mode);
const char *cxl_memdev_get_firmware_version(struct cxl_memdev *memdev);
size_t cxl_memdev_get_label_size(struct cxl_memdev *memdev);
int cxl_memdev_nvdimm_bridge_active(struct cxl_memdev *memdev);
@@ -422,11 +423,23 @@ enum cxl_decoder_mode {
CXL_DECODER_MODE_MIXED,
CXL_DECODER_MODE_PMEM,
CXL_DECODER_MODE_RAM,
+ CXL_DECODER_MODE_DC0,
+ CXL_DECODER_MODE_DC1,
+ CXL_DECODER_MODE_DC2,
+ CXL_DECODER_MODE_DC3,
+ CXL_DECODER_MODE_DC4,
+ CXL_DECODER_MODE_DC5,
+ CXL_DECODER_MODE_DC6,
+ CXL_DECODER_MODE_DC7,
};
enum cxl_decoder_mode cxl_decoder_get_mode(struct cxl_decoder *decoder);
+const char *cxl_decoder_mode_name(enum cxl_decoder_mode mode);
+enum cxl_decoder_mode cxl_decoder_mode_from_ident(const char *ident);
+bool cxl_decoder_mode_is_dc(enum cxl_decoder_mode mode);
int cxl_decoder_set_mode(struct cxl_decoder *decoder, enum cxl_decoder_mode mode);
bool cxl_decoder_is_pmem_capable(struct cxl_decoder *decoder);
+bool cxl_decoder_is_dc_capable(struct cxl_decoder *decoder, enum cxl_decoder_mode mode);
bool cxl_decoder_is_volatile_capable(struct cxl_decoder *decoder);
bool cxl_decoder_is_mem_capable(struct cxl_decoder *decoder);
bool cxl_decoder_is_accelmem_capable(struct cxl_decoder *decoder);
@@ -558,6 +571,7 @@ enum cxl_region_mode {
CXL_REGION_MODE_MIXED = CXL_DECODER_MODE_MIXED,
CXL_REGION_MODE_PMEM = CXL_DECODER_MODE_PMEM,
CXL_REGION_MODE_RAM = CXL_DECODER_MODE_RAM,
+ CXL_REGION_MODE_DC,
};
const char *cxl_region_mode_name(enum cxl_region_mode mode);
enum cxl_region_mode cxl_region_mode_from_ident(const char *ident);
@@ -615,7 +629,8 @@ cxl_region_get_daxctl_region() returns an 'struct daxctl_region *' that
can be used with other libdaxctl APIs.
Regions now have a mode distinct from decoders. cxl_region_get_mode() is
-deprecated in favor of cxl_region_get_region_mode().
+deprecated in favor of cxl_region_get_region_mode(). Dynamic capacity regions
+require the use of cxl_region_get_region_mode().
include::../../copyright.txt[]
diff --git a/cxl/lib/libcxl.c b/cxl/lib/libcxl.c
index 35a40091e8f5813c1b3ef2ffb931c9ec584b02ad..df250db9dbacb2f0f34e8a592ce194159584fe4f 100644
--- a/cxl/lib/libcxl.c
+++ b/cxl/lib/libcxl.c
@@ -1304,6 +1304,19 @@ static void *add_cxl_memdev(void *parent, int id, const char *cxlmem_base)
else
memdev->ram_qos_class = atoi(buf);
+ memdev->dc_partition_count = 0;
+ for (int partition = 0; partition < MAX_NUM_DC_REGIONS; partition++) {
+ sprintf(path, "%s/dc%d/size", cxlmem_base, partition);
+ if (sysfs_read_attr(ctx, path, buf) < 0)
+ continue;
+ memdev->dc_size[partition] = strtoull(buf, NULL, 0);
+ memdev->dc_partition_count++;
+ sprintf(path, "%s/dc%d/qos_class", cxlmem_base, partition);
+ if (sysfs_read_attr(ctx, path, buf) < 0)
+ continue;
+ memdev->dc_qos_class[partition] = strtoull(buf, NULL, 0);
+ }
+
sprintf(path, "%s/payload_max", cxlmem_base);
if (sysfs_read_attr(ctx, path, buf) == 0) {
memdev->payload_max = strtoull(buf, NULL, 0);
@@ -1540,6 +1553,23 @@ CXL_EXPORT int cxl_memdev_get_ram_qos_class(struct cxl_memdev *memdev)
return memdev->ram_qos_class;
}
+static int cxl_decoder_dc_mode_to_index(enum cxl_decoder_mode mode)
+{
+ if (mode < CXL_DECODER_MODE_DC0 || mode > CXL_DECODER_MODE_DC7)
+ return -EINVAL;
+ return mode - CXL_DECODER_MODE_DC0;
+}
+
+CXL_EXPORT unsigned long long cxl_memdev_get_dc_size(struct cxl_memdev *memdev,
+ enum cxl_decoder_mode mode)
+{
+ int index = cxl_decoder_dc_mode_to_index(mode);
+
+ if (index < 0)
+ return 0;
+ return memdev->dc_size[index];
+}
+
CXL_EXPORT const char *cxl_memdev_get_firmware_verison(struct cxl_memdev *memdev)
{
return memdev->firmware_version;
@@ -2275,6 +2305,22 @@ static void *add_cxl_decoder(void *parent, int id, const char *cxldecoder_base)
decoder->mode = CXL_DECODER_MODE_RAM;
else if (strcmp(buf, "pmem") == 0)
decoder->mode = CXL_DECODER_MODE_PMEM;
+ else if (strcmp(buf, "dc0") == 0)
+ decoder->mode = CXL_DECODER_MODE_DC0;
+ else if (strcmp(buf, "dc1") == 0)
+ decoder->mode = CXL_DECODER_MODE_DC1;
+ else if (strcmp(buf, "dc2") == 0)
+ decoder->mode = CXL_DECODER_MODE_DC2;
+ else if (strcmp(buf, "dc3") == 0)
+ decoder->mode = CXL_DECODER_MODE_DC3;
+ else if (strcmp(buf, "dc4") == 0)
+ decoder->mode = CXL_DECODER_MODE_DC4;
+ else if (strcmp(buf, "dc5") == 0)
+ decoder->mode = CXL_DECODER_MODE_DC5;
+ else if (strcmp(buf, "dc6") == 0)
+ decoder->mode = CXL_DECODER_MODE_DC6;
+ else if (strcmp(buf, "dc7") == 0)
+ decoder->mode = CXL_DECODER_MODE_DC7;
else if (strcmp(buf, "mixed") == 0)
decoder->mode = CXL_DECODER_MODE_MIXED;
else if (strcmp(buf, "none") == 0)
@@ -2318,6 +2364,8 @@ static void *add_cxl_decoder(void *parent, int id, const char *cxldecoder_base)
case CXL_PORT_SWITCH:
decoder->pmem_capable = true;
decoder->volatile_capable = true;
+ for (unsigned index = 0; index < MAX_NUM_DC_REGIONS; index++)
+ decoder->dc_capable[index] = true;
decoder->mem_capable = true;
decoder->accelmem_capable = true;
sprintf(path, "%s/locked", cxldecoder_base);
@@ -2341,6 +2389,14 @@ static void *add_cxl_decoder(void *parent, int id, const char *cxldecoder_base)
{ "cap_type2", &decoder->accelmem_capable },
{ "cap_type3", &decoder->mem_capable },
{ "cap_ram", &decoder->volatile_capable },
+ { "cap_ram", &decoder->dc_capable[0] },
+ { "cap_ram", &decoder->dc_capable[1] },
+ { "cap_ram", &decoder->dc_capable[2] },
+ { "cap_ram", &decoder->dc_capable[3] },
+ { "cap_ram", &decoder->dc_capable[4] },
+ { "cap_ram", &decoder->dc_capable[5] },
+ { "cap_ram", &decoder->dc_capable[6] },
+ { "cap_ram", &decoder->dc_capable[7] },
{ "cap_pmem", &decoder->pmem_capable },
{ "locked", &decoder->locked },
};
@@ -2592,6 +2648,30 @@ CXL_EXPORT int cxl_decoder_set_mode(struct cxl_decoder *decoder,
case CXL_DECODER_MODE_RAM:
sprintf(buf, "ram");
break;
+ case CXL_DECODER_MODE_DC0:
+ sprintf(buf, "dc0");
+ break;
+ case CXL_DECODER_MODE_DC1:
+ sprintf(buf, "dc1");
+ break;
+ case CXL_DECODER_MODE_DC2:
+ sprintf(buf, "dc2");
+ break;
+ case CXL_DECODER_MODE_DC3:
+ sprintf(buf, "dc3");
+ break;
+ case CXL_DECODER_MODE_DC4:
+ sprintf(buf, "dc4");
+ break;
+ case CXL_DECODER_MODE_DC5:
+ sprintf(buf, "dc5");
+ break;
+ case CXL_DECODER_MODE_DC6:
+ sprintf(buf, "dc6");
+ break;
+ case CXL_DECODER_MODE_DC7:
+ sprintf(buf, "dc7");
+ break;
default:
err(ctx, "%s: unsupported mode: %d\n",
cxl_decoder_get_devname(decoder), mode);
@@ -2648,6 +2728,16 @@ CXL_EXPORT bool cxl_decoder_is_mem_capable(struct cxl_decoder *decoder)
return decoder->mem_capable;
}
+CXL_EXPORT bool cxl_decoder_is_dc_capable(struct cxl_decoder *decoder,
+ enum cxl_decoder_mode mode)
+{
+ int index = cxl_decoder_dc_mode_to_index(mode);
+
+ if (index < 0)
+ return false;
+ return decoder->dc_capable[index];
+}
+
CXL_EXPORT bool cxl_decoder_is_accelmem_capable(struct cxl_decoder *decoder)
{
return decoder->accelmem_capable;
@@ -2717,6 +2807,8 @@ static struct cxl_region *cxl_decoder_create_region(struct cxl_decoder *decoder,
sprintf(path, "%s/create_pmem_region", decoder->dev_path);
else if (mode == CXL_REGION_MODE_RAM)
sprintf(path, "%s/create_ram_region", decoder->dev_path);
+ else if (mode == CXL_REGION_MODE_DC)
+ sprintf(path, "%s/create_dc_region", decoder->dev_path);
rc = sysfs_read_attr(ctx, path, buf);
if (rc < 0) {
@@ -2768,6 +2860,12 @@ cxl_decoder_create_ram_region(struct cxl_decoder *decoder)
return cxl_decoder_create_region(decoder, CXL_REGION_MODE_RAM);
}
+CXL_EXPORT struct cxl_region *
+cxl_decoder_create_dc_region(struct cxl_decoder *decoder)
+{
+ return cxl_decoder_create_region(decoder, CXL_REGION_MODE_DC);
+}
+
CXL_EXPORT int cxl_decoder_get_nr_targets(struct cxl_decoder *decoder)
{
return decoder->nr_targets;
diff --git a/cxl/lib/libcxl.sym b/cxl/lib/libcxl.sym
index 17a660f508ad1e053af2992824535ccf7ce877b2..fdb227789985443a13c72751bbd42ab383db5f97 100644
--- a/cxl/lib/libcxl.sym
+++ b/cxl/lib/libcxl.sym
@@ -292,4 +292,7 @@ global:
LIBCXL_9 {
global:
cxl_region_get_region_mode;
+ cxl_memdev_get_dc_size;
+ cxl_decoder_is_dc_capable;
+ cxl_decoder_create_dc_region;
} LIBECXL_8;
diff --git a/cxl/lib/private.h b/cxl/lib/private.h
index 0f45be89b6a00477d13fb6d7f1906213a3073c48..3efa230bfb632e6c6048aadd18f799b07d4bdfd3 100644
--- a/cxl/lib/private.h
+++ b/cxl/lib/private.h
@@ -47,6 +47,9 @@ struct cxl_memdev {
struct list_node list;
unsigned long long pmem_size;
unsigned long long ram_size;
+ unsigned long long dc_size[MAX_NUM_DC_REGIONS];
+ unsigned long long dc_qos_class[MAX_NUM_DC_REGIONS];
+ int dc_partition_count;
int ram_qos_class;
int pmem_qos_class;
int payload_max;
@@ -140,6 +143,7 @@ struct cxl_decoder {
bool pmem_capable;
bool volatile_capable;
bool mem_capable;
+ bool dc_capable[MAX_NUM_DC_REGIONS];
bool accelmem_capable;
bool locked;
enum cxl_decoder_target_type target_type;
diff --git a/cxl/libcxl.h b/cxl/libcxl.h
index 06b87a0924faafec6c80eca83ea7551d4e117256..d7f8a37816f236acd71fc834eae70a7a17a2721a 100644
--- a/cxl/libcxl.h
+++ b/cxl/libcxl.h
@@ -72,6 +72,9 @@ int cxl_memdev_get_minor(struct cxl_memdev *memdev);
struct cxl_ctx *cxl_memdev_get_ctx(struct cxl_memdev *memdev);
unsigned long long cxl_memdev_get_pmem_size(struct cxl_memdev *memdev);
unsigned long long cxl_memdev_get_ram_size(struct cxl_memdev *memdev);
+enum cxl_decoder_mode;
+unsigned long long cxl_memdev_get_dc_size(struct cxl_memdev *memdev,
+ enum cxl_decoder_mode mode);
int cxl_memdev_get_pmem_qos_class(struct cxl_memdev *memdev);
int cxl_memdev_get_ram_qos_class(struct cxl_memdev *memdev);
const char *cxl_memdev_get_firmware_verison(struct cxl_memdev *memdev);
@@ -191,11 +194,20 @@ unsigned long long
cxl_decoder_get_max_available_extent(struct cxl_decoder *decoder);
int cxl_root_decoder_get_qos_class(struct cxl_decoder *decoder);
+#define MAX_NUM_DC_REGIONS 8
enum cxl_decoder_mode {
CXL_DECODER_MODE_NONE,
CXL_DECODER_MODE_MIXED,
CXL_DECODER_MODE_PMEM,
CXL_DECODER_MODE_RAM,
+ CXL_DECODER_MODE_DC0,
+ CXL_DECODER_MODE_DC1,
+ CXL_DECODER_MODE_DC2,
+ CXL_DECODER_MODE_DC3,
+ CXL_DECODER_MODE_DC4,
+ CXL_DECODER_MODE_DC5,
+ CXL_DECODER_MODE_DC6,
+ CXL_DECODER_MODE_DC7,
};
static inline const char *cxl_decoder_mode_name(enum cxl_decoder_mode mode)
@@ -205,9 +217,17 @@ static inline const char *cxl_decoder_mode_name(enum cxl_decoder_mode mode)
[CXL_DECODER_MODE_MIXED] = "mixed",
[CXL_DECODER_MODE_PMEM] = "pmem",
[CXL_DECODER_MODE_RAM] = "ram",
+ [CXL_DECODER_MODE_DC0] = "dc0",
+ [CXL_DECODER_MODE_DC1] = "dc1",
+ [CXL_DECODER_MODE_DC2] = "dc2",
+ [CXL_DECODER_MODE_DC3] = "dc3",
+ [CXL_DECODER_MODE_DC4] = "dc4",
+ [CXL_DECODER_MODE_DC5] = "dc5",
+ [CXL_DECODER_MODE_DC6] = "dc6",
+ [CXL_DECODER_MODE_DC7] = "dc7",
};
- if (mode < CXL_DECODER_MODE_NONE || mode > CXL_DECODER_MODE_RAM)
+ if (mode < CXL_DECODER_MODE_NONE || mode > CXL_DECODER_MODE_DC7)
mode = CXL_DECODER_MODE_NONE;
return names[mode];
}
@@ -221,9 +241,30 @@ cxl_decoder_mode_from_ident(const char *ident)
return CXL_DECODER_MODE_RAM;
else if (strcmp(ident, "pmem") == 0)
return CXL_DECODER_MODE_PMEM;
+ else if (strcmp(ident, "dc0") == 0)
+ return CXL_DECODER_MODE_DC0;
+ else if (strcmp(ident, "dc1") == 0)
+ return CXL_DECODER_MODE_DC1;
+ else if (strcmp(ident, "dc2") == 0)
+ return CXL_DECODER_MODE_DC2;
+ else if (strcmp(ident, "dc3") == 0)
+ return CXL_DECODER_MODE_DC3;
+ else if (strcmp(ident, "dc4") == 0)
+ return CXL_DECODER_MODE_DC4;
+ else if (strcmp(ident, "dc5") == 0)
+ return CXL_DECODER_MODE_DC5;
+ else if (strcmp(ident, "dc6") == 0)
+ return CXL_DECODER_MODE_DC6;
+ else if (strcmp(ident, "dc7") == 0)
+ return CXL_DECODER_MODE_DC7;
return CXL_DECODER_MODE_NONE;
}
+static inline bool cxl_decoder_mode_is_dc(enum cxl_decoder_mode mode)
+{
+ return (mode >= CXL_DECODER_MODE_DC0 && mode <= CXL_DECODER_MODE_DC7);
+}
+
enum cxl_decoder_mode cxl_decoder_get_mode(struct cxl_decoder *decoder);
int cxl_decoder_set_mode(struct cxl_decoder *decoder,
enum cxl_decoder_mode mode);
@@ -248,6 +289,8 @@ enum cxl_decoder_target_type {
enum cxl_decoder_target_type
cxl_decoder_get_target_type(struct cxl_decoder *decoder);
bool cxl_decoder_is_pmem_capable(struct cxl_decoder *decoder);
+bool cxl_decoder_is_dc_capable(struct cxl_decoder *decoder,
+ enum cxl_decoder_mode mode);
bool cxl_decoder_is_volatile_capable(struct cxl_decoder *decoder);
bool cxl_decoder_is_mem_capable(struct cxl_decoder *decoder);
bool cxl_decoder_is_accelmem_capable(struct cxl_decoder *decoder);
@@ -258,6 +301,7 @@ unsigned int cxl_decoder_get_interleave_ways(struct cxl_decoder *decoder);
struct cxl_region *cxl_decoder_get_region(struct cxl_decoder *decoder);
struct cxl_region *cxl_decoder_create_pmem_region(struct cxl_decoder *decoder);
struct cxl_region *cxl_decoder_create_ram_region(struct cxl_decoder *decoder);
+struct cxl_region *cxl_decoder_create_dc_region(struct cxl_decoder *decoder);
struct cxl_decoder *cxl_decoder_get_by_name(struct cxl_ctx *ctx,
const char *ident);
struct cxl_memdev *cxl_decoder_get_memdev(struct cxl_decoder *decoder);
@@ -308,6 +352,7 @@ enum cxl_region_mode {
CXL_REGION_MODE_MIXED = CXL_DECODER_MODE_MIXED,
CXL_REGION_MODE_PMEM = CXL_DECODER_MODE_PMEM,
CXL_REGION_MODE_RAM = CXL_DECODER_MODE_RAM,
+ CXL_REGION_MODE_DC,
};
static inline const char *cxl_region_mode_name(enum cxl_region_mode mode)
@@ -317,9 +362,10 @@ static inline const char *cxl_region_mode_name(enum cxl_region_mode mode)
[CXL_REGION_MODE_MIXED] = "mixed",
[CXL_REGION_MODE_PMEM] = "pmem",
[CXL_REGION_MODE_RAM] = "ram",
+ [CXL_REGION_MODE_DC] = "dc",
};
- if (mode < CXL_REGION_MODE_NONE || mode > CXL_REGION_MODE_RAM)
+ if (mode < CXL_REGION_MODE_NONE || mode > CXL_REGION_MODE_DC)
mode = CXL_REGION_MODE_NONE;
return names[mode];
}
@@ -333,6 +379,8 @@ cxl_region_mode_from_ident(const char *ident)
return CXL_REGION_MODE_RAM;
else if (strcmp(ident, "pmem") == 0)
return CXL_REGION_MODE_PMEM;
+ else if (strcmp(ident, "dc") == 0)
+ return CXL_REGION_MODE_DC;
return CXL_REGION_MODE_NONE;
}
--
2.47.1
next prev parent reply other threads:[~2024-12-15 2:58 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-12-15 2:58 [ndctl PATCH v4 0/9] ndctl: Dynamic Capacity additions for cxl-cli Ira Weiny
2024-12-15 2:58 ` [ndctl PATCH v4 1/9] ndctl/cxl-events: Don't fail test until event counts are reported Ira Weiny
2024-12-15 2:58 ` [ndctl PATCH v4 2/9] ndctl/cxl/region: Report max size for region creation Ira Weiny
2024-12-15 2:58 ` [ndctl PATCH v4 3/9] libcxl: Separate region mode from decoder mode Ira Weiny
2024-12-15 2:58 ` [ndctl PATCH v4 4/9] cxl/region: Use new region mode in cxl-cli Ira Weiny
2024-12-15 2:58 ` Ira Weiny [this message]
2025-02-11 3:12 ` [ndctl PATCH v4 5/9] libcxl: Add Dynamic Capacity region support Alison Schofield
2024-12-15 2:58 ` [ndctl PATCH v4 6/9] cxl/region: Add cxl-cli support for DCD regions Ira Weiny
2025-02-11 3:21 ` Alison Schofield
2024-12-15 2:58 ` [ndctl PATCH v4 7/9] libcxl: Add extent functionality to DC regions Ira Weiny
2024-12-15 2:58 ` [ndctl PATCH v4 8/9] cxl/region: Add extent output to region query Ira Weiny
2025-02-11 3:24 ` Alison Schofield
2025-02-12 22:03 ` Ira Weiny
2024-12-15 2:58 ` [ndctl PATCH v4 9/9] cxl/test: Add Dynamic Capacity tests Ira Weiny
2025-02-11 3:33 ` Alison Schofield
2025-02-11 2:47 ` [ndctl PATCH v4 0/9] ndctl: Dynamic Capacity additions for cxl-cli Alison Schofield
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=20241214-dcd-region2-v4-5-36550a97f8e2@intel.com \
--to=ira.weiny@intel.com \
--cc=alison.schofield@intel.com \
--cc=dan.j.williams@intel.com \
--cc=dave.jiang@intel.com \
--cc=fan.ni@samsung.com \
--cc=jonathan.cameron@Huawei.com \
--cc=linux-cxl@vger.kernel.org \
--cc=nvdimm@lists.linux.dev \
--cc=sushant1.kumar@intel.com \
--cc=vishal.l.verma@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox