Add spm_node bit to cxl region, forward it to the dax device.

This allows auto-hotplug to occur without an intermediate udev
step to poke the DAX device spm_node bit.

Signed-off-by: Gregory Price <[email protected]>
---
 drivers/cxl/core/region.c | 30 ++++++++++++++++++++++++++++++
 drivers/cxl/cxl.h         |  2 ++
 drivers/dax/cxl.c         |  1 +
 3 files changed, 33 insertions(+)

diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
index b06fee1978ba..3348b09dfe9a 100644
--- a/drivers/cxl/core/region.c
+++ b/drivers/cxl/core/region.c
@@ -754,6 +754,35 @@ static ssize_t size_show(struct device *dev, struct 
device_attribute *attr,
 }
 static DEVICE_ATTR_RW(size);
 
+static ssize_t spm_node_show(struct device *dev,
+                            struct device_attribute *attr, char *buf)
+{
+       struct cxl_region *cxlr = to_cxl_region(dev);
+
+       return sysfs_emit(buf, "%d\n", cxlr->spm_node);
+}
+
+static ssize_t spm_node_store(struct device *dev,
+                                     struct device_attribute *attr,
+                                     const char *buf, size_t len)
+{
+       struct cxl_region *cxlr = to_cxl_region(dev);
+       bool val;
+       int rc;
+
+       rc = kstrtobool(buf, &val);
+       if (rc)
+               return rc;
+
+       ACQUIRE(rwsem_write_kill, rwsem)(&cxl_rwsem.region);
+       if ((rc = ACQUIRE_ERR(rwsem_read_intr, &rwsem)))
+               return rc;
+
+       cxlr->spm_node = val;
+       return len;
+}
+static DEVICE_ATTR_RW(spm_node);
+
 static struct attribute *cxl_region_attrs[] = {
        &dev_attr_uuid.attr,
        &dev_attr_commit.attr,
@@ -762,6 +791,7 @@ static struct attribute *cxl_region_attrs[] = {
        &dev_attr_resource.attr,
        &dev_attr_size.attr,
        &dev_attr_mode.attr,
+       &dev_attr_spm_node.attr,
        NULL,
 };
 
diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
index 231ddccf8977..ba7cde06dfd3 100644
--- a/drivers/cxl/cxl.h
+++ b/drivers/cxl/cxl.h
@@ -530,6 +530,7 @@ enum cxl_partition_mode {
  * @coord: QoS access coordinates for the region
  * @node_notifier: notifier for setting the access coordinates to node
  * @adist_notifier: notifier for calculating the abstract distance of node
+ * @spm_node: memory can only be added to specific purpose NUMA nodes
  */
 struct cxl_region {
        struct device dev;
@@ -543,6 +544,7 @@ struct cxl_region {
        struct access_coordinate coord[ACCESS_COORDINATE_MAX];
        struct notifier_block node_notifier;
        struct notifier_block adist_notifier;
+       bool spm_node;
 };
 
 struct cxl_nvdimm_bridge {
diff --git a/drivers/dax/cxl.c b/drivers/dax/cxl.c
index 13cd94d32ff7..968d23fc19ed 100644
--- a/drivers/dax/cxl.c
+++ b/drivers/dax/cxl.c
@@ -27,6 +27,7 @@ static int cxl_dax_region_probe(struct device *dev)
                .id = -1,
                .size = range_len(&cxlr_dax->hpa_range),
                .memmap_on_memory = true,
+               .spm_node = cxlr->spm_node,
        };
 
        return PTR_ERR_OR_ZERO(devm_create_dev_dax(&data));
-- 
2.51.1


Reply via email to