cxl/hdm: Add 'mode' attribute to decoder objects
authorDan Williams <dan.j.williams@intel.com>
Mon, 23 May 2022 19:15:35 +0000 (12:15 -0700)
committerDan Williams <dan.j.williams@intel.com>
Fri, 22 Jul 2022 00:19:23 +0000 (17:19 -0700)
Recall that the Device Physical Address (DPA) space of a CXL Memory
Expander is potentially partitioned into a volatile and persistent
portion. A decoder maps a Host Physical Address (HPA) range to a DPA
range and that translation depends on the value of all previous (lower
instance number) decoders before the current one.

In preparation for allowing dynamic provisioning of regions, decoders
need an ABI to indicate which DPA partition a decoder targets. This ABI
needs to be prepared for the possibility that some other agent committed
and locked a decoder that spans the partition boundary.

Add 'decoderX.Y/mode' to endpoint decoders that indicates which
partition 'ram' / 'pmem' the decoder targets, or 'mixed' if the decoder
currently spans the partition boundary.

Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Link: https://lore.kernel.org/r/165603881967.551046.6007594190951596439.stgit@dwillia2-xfh
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Documentation/ABI/testing/sysfs-bus-cxl
drivers/cxl/core/hdm.c
drivers/cxl/core/port.c
drivers/cxl/cxl.h

index 5ada6d9543d32789fd26885f58886bdfdd23ea31..0b672248d126d8d2ce336583ec21f6ab77bd4e6c 100644 (file)
@@ -190,3 +190,19 @@ Description:
                found to support CDAT data.  If it is present and the length of
                the data is 0 reading the CDAT data failed.  Otherwise the CDAT
                data is reported.
+
+
+What:          /sys/bus/cxl/devices/decoderX.Y/mode
+Date:          May, 2022
+KernelVersion: v5.20
+Contact:       linux-cxl@vger.kernel.org
+Description:
+               (RO) 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.
index 47e3af440b3da4993eed5701de092b2381adaf7c..c2cff5783fda8bd3398d1699c2d0674cd6ba1100 100644 (file)
@@ -226,6 +226,16 @@ static int __cxl_dpa_reserve(struct cxl_endpoint_decoder *cxled,
        cxled->dpa_res = res;
        cxled->skip = skipped;
 
+       if (resource_contains(&cxlds->pmem_res, res))
+               cxled->mode = CXL_DECODER_PMEM;
+       else if (resource_contains(&cxlds->ram_res, res))
+               cxled->mode = CXL_DECODER_RAM;
+       else {
+               dev_dbg(dev, "decoder%d.%d: %pr mixed\n", port->id,
+                       cxled->cxld.id, cxled->dpa_res);
+               cxled->mode = CXL_DECODER_MIXED;
+       }
+
        return 0;
 }
 
index 2cfa870428c25f90e4ce4627182f6514cf75c0f4..9a312f2e2d3542f782042d2eda5f18f140fa67c1 100644 (file)
@@ -172,6 +172,25 @@ static ssize_t target_list_show(struct device *dev,
 }
 static DEVICE_ATTR_RO(target_list);
 
+static ssize_t mode_show(struct device *dev, struct device_attribute *attr,
+                        char *buf)
+{
+       struct cxl_endpoint_decoder *cxled = to_cxl_endpoint_decoder(dev);
+
+       switch (cxled->mode) {
+       case CXL_DECODER_RAM:
+               return sysfs_emit(buf, "ram\n");
+       case CXL_DECODER_PMEM:
+               return sysfs_emit(buf, "pmem\n");
+       case CXL_DECODER_NONE:
+               return sysfs_emit(buf, "none\n");
+       case CXL_DECODER_MIXED:
+       default:
+               return sysfs_emit(buf, "mixed\n");
+       }
+}
+static DEVICE_ATTR_RO(mode);
+
 static struct attribute *cxl_decoder_base_attrs[] = {
        &dev_attr_start.attr,
        &dev_attr_size.attr,
@@ -222,6 +241,7 @@ static const struct attribute_group *cxl_decoder_switch_attribute_groups[] = {
 
 static struct attribute *cxl_decoder_endpoint_attrs[] = {
        &dev_attr_target_type.attr,
+       &dev_attr_mode.attr,
        NULL,
 };
 
index 5fe8b59a0b18101ac438429869ee98d71ff0f49c..afaa76f065f9bc43828e76565e5ae3ea35cc1829 100644 (file)
@@ -241,16 +241,25 @@ struct cxl_decoder {
        unsigned long flags;
 };
 
+enum cxl_decoder_mode {
+       CXL_DECODER_NONE,
+       CXL_DECODER_RAM,
+       CXL_DECODER_PMEM,
+       CXL_DECODER_MIXED,
+};
+
 /**
  * struct cxl_endpoint_decoder - Endpoint  / SPA to DPA decoder
  * @cxld: base cxl_decoder_object
  * @dpa_res: actively claimed DPA span of this decoder
  * @skip: offset into @dpa_res where @cxld.hpa_range maps
+ * @mode: which memory type / access-mode-partition this decoder targets
  */
 struct cxl_endpoint_decoder {
        struct cxl_decoder cxld;
        struct resource *dpa_res;
        resource_size_t skip;
+       enum cxl_decoder_mode mode;
 };
 
 /**