@@ -257,22 +257,23 @@ Description:
What: /sys/bus/cxl/devices/decoderX.Y/mode
Date: May, 2022
-KernelVersion: v6.0
+KernelVersion: v6.0, v6.6 (dcY)
Contact: linux-cxl@vger.kernel.org
Description:
(RW) When a CXL decoder is of devtype "cxl_decoder_endpoint" it
translates from a host physical address range, to a device local
address range. Device-local address ranges are further split
- into a 'ram' (volatile memory) range and 'pmem' (persistent
- memory) range. The 'mode' attribute emits one of 'ram', 'pmem',
- 'mixed', or 'none'. The 'mixed' indication is for error cases
- when a decoder straddles the volatile/persistent partition
- boundary, and 'none' indicates the decoder is not actively
- decoding, or no DPA allocation policy has been set.
+ into a 'ram' (volatile memory) range, 'pmem' (persistent
+ memory) range, or Dynamic Capacity (DC) range. The 'mode'
+ attribute emits one of 'ram', 'pmem', 'dcY', 'mixed', or
+ 'none'. The 'mixed' indication is for error cases when a
+ decoder straddles the volatile/persistent partition boundary,
+ and 'none' indicates the decoder is not actively decoding, or
+ no DPA allocation policy has been set.
'mode' can be written, when the decoder is in the 'disabled'
- state, with either 'ram' or 'pmem' to set the boundaries for the
- next allocation.
+ state, with 'ram', 'pmem', or 'dcY' to set the boundaries for
+ the next allocation.
What: /sys/bus/cxl/devices/decoderX.Y/dpa_resource
@@ -267,6 +267,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)
@@ -429,6 +442,7 @@ int cxl_dpa_set_mode(struct cxl_endpoint_decoder *cxled,
switch (mode) {
case CXL_DECODER_RAM:
case CXL_DECODER_PMEM:
+ case CXL_DECODER_DC0 ... CXL_DECODER_DC7:
break;
default:
dev_dbg(dev, "unsupported mode: %d\n", mode);
@@ -456,6 +470,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");
+ rc = -ENXIO;
+ goto out;
+ }
+ }
+
cxled->mode = mode;
rc = 0;
out:
@@ -197,6 +197,22 @@ static ssize_t mode_store(struct device *dev, struct device_attribute *attr,
mode = CXL_DECODER_PMEM;
else if (sysfs_streq(buf, "ram"))
mode = CXL_DECODER_RAM;
+ else if (sysfs_streq(buf, "dc0"))
+ mode = CXL_DECODER_DC0;
+ else if (sysfs_streq(buf, "dc1"))
+ mode = CXL_DECODER_DC1;
+ else if (sysfs_streq(buf, "dc2"))
+ mode = CXL_DECODER_DC2;
+ else if (sysfs_streq(buf, "dc3"))
+ mode = CXL_DECODER_DC3;
+ else if (sysfs_streq(buf, "dc4"))
+ mode = CXL_DECODER_DC4;
+ else if (sysfs_streq(buf, "dc5"))
+ mode = CXL_DECODER_DC5;
+ else if (sysfs_streq(buf, "dc6"))
+ mode = CXL_DECODER_DC6;
+ else if (sysfs_streq(buf, "dc7"))
+ mode = CXL_DECODER_DC7;
else
return -EINVAL;