@@ -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[]
@@ -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;
@@ -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;
@@ -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;
@@ -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;
}