]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
cxl/memdev: Introduce cxl_class_memdev_type
authorDan Williams <djbw@kernel.org>
Tue, 19 May 2026 21:01:57 +0000 (14:01 -0700)
committerDave Jiang <dave.jiang@intel.com>
Fri, 12 Jun 2026 20:47:29 +0000 (13:47 -0700)
In preparation for memdev's without mailbox related infrastructure,
introduce cxl_class_memdev_type as a superset of a cxl_memdev_type.
Effectively the only difference is that cxl_class_memdev_type exports
common sysfs attributes where cxl_memdev_type has none.

Related to this is all the cxl_mem_probe() paths that assume the presence
of a class device mailbox are updated to skip that requirement.

Co-developed-by: Alejandro Lucero <alucerop@amd.com>
Signed-off-by: Alejandro Lucero <alucerop@amd.com>
Signed-off-by: Dan Williams <djbw@kernel.org>
Tested-by: ALejandro Lucero <alucerop@amd.com>
Reviewed-by: Dave Jiang <dave.jiang@intel.com>
Link: https://patch.msgid.link/20260519210158.1499795-5-djbw@kernel.org
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
drivers/cxl/core/memdev.c
drivers/cxl/mem.c

index 91c99eeea92ce4d6c2fffc6222a39a239af46d33..33a3d2e7b13af95dd4639d065d6f5b4de89ffe50 100644 (file)
@@ -574,16 +574,23 @@ void cxl_memdev_update_perf(struct cxl_memdev *cxlmd)
 }
 EXPORT_SYMBOL_NS_GPL(cxl_memdev_update_perf, "CXL");
 
-static const struct device_type cxl_memdev_type = {
+static const struct device_type cxl_class_memdev_type = {
        .name = "cxl_memdev",
        .release = cxl_memdev_release,
        .devnode = cxl_memdev_devnode,
        .groups = cxl_memdev_attribute_groups,
 };
 
+static const struct device_type cxl_memdev_type = {
+       .name = "cxl_memdev",
+       .release = cxl_memdev_release,
+       .devnode = cxl_memdev_devnode,
+};
+
 bool is_cxl_memdev(const struct device *dev)
 {
-       return dev->type == &cxl_memdev_type;
+       return (dev->type == &cxl_class_memdev_type ||
+               dev->type == &cxl_memdev_type);
 }
 EXPORT_SYMBOL_NS_GPL(is_cxl_memdev, "CXL");
 
@@ -712,7 +719,10 @@ static struct cxl_memdev *cxl_memdev_alloc(struct cxl_dev_state *cxlds,
        dev->parent = get_device(cxlds->dev);
        dev->bus = &cxl_bus_type;
        dev->devt = MKDEV(cxl_mem_major, cxlmd->id);
-       dev->type = &cxl_memdev_type;
+       if (cxlds->type == CXL_DEVTYPE_DEVMEM)
+               dev->type = &cxl_memdev_type;
+       else
+               dev->type = &cxl_class_memdev_type;
        device_set_pm_not_required(dev);
        INIT_WORK(&cxlmd->detach_work, detach_memdev);
 
index fcffe24dcb42f80510ccf79511af8f0d97813dc2..ff858318091f18fbd1c3003d539d308a329a5632 100644 (file)
@@ -65,6 +65,26 @@ static int cxl_debugfs_poison_clear(void *data, u64 dpa)
 DEFINE_DEBUGFS_ATTRIBUTE(cxl_poison_clear_fops, NULL,
                         cxl_debugfs_poison_clear, "%llx\n");
 
+static void cxl_memdev_poison_enable(struct cxl_memdev_state *mds,
+                                    struct cxl_memdev *cxlmd,
+                                    struct dentry *dentry)
+{
+       /*
+        * Avoid poison debugfs for DEVMEM aka accelerators as they rely on
+        * cxl_memdev_state.
+        */
+       if (!mds)
+               return;
+
+       if (test_bit(CXL_POISON_ENABLED_INJECT, mds->poison.enabled_cmds))
+               debugfs_create_file("inject_poison", 0200, dentry, cxlmd,
+                                   &cxl_poison_inject_fops);
+
+       if (test_bit(CXL_POISON_ENABLED_CLEAR, mds->poison.enabled_cmds))
+               debugfs_create_file("clear_poison", 0200, dentry, cxlmd,
+                                   &cxl_poison_clear_fops);
+}
+
 static int cxl_mem_probe(struct device *dev)
 {
        struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
@@ -92,12 +112,7 @@ static int cxl_mem_probe(struct device *dev)
        dentry = cxl_debugfs_create_dir(dev_name(dev));
        debugfs_create_devm_seqfile(dev, "dpamem", dentry, cxl_mem_dpa_show);
 
-       if (test_bit(CXL_POISON_ENABLED_INJECT, mds->poison.enabled_cmds))
-               debugfs_create_file("inject_poison", 0200, dentry, cxlmd,
-                                   &cxl_poison_inject_fops);
-       if (test_bit(CXL_POISON_ENABLED_CLEAR, mds->poison.enabled_cmds))
-               debugfs_create_file("clear_poison", 0200, dentry, cxlmd,
-                                   &cxl_poison_clear_fops);
+       cxl_memdev_poison_enable(mds, cxlmd, dentry);
 
        rc = devm_add_action_or_reset(dev, remove_debugfs, dentry);
        if (rc)
@@ -206,16 +221,24 @@ static ssize_t trigger_poison_list_store(struct device *dev,
 }
 static DEVICE_ATTR_WO(trigger_poison_list);
 
-static umode_t cxl_mem_visible(struct kobject *kobj, struct attribute *a, int n)
+static bool cxl_poison_attr_visible(struct kobject *kobj, struct attribute *a)
 {
        struct device *dev = kobj_to_dev(kobj);
        struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
        struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlmd->cxlds);
 
-       if (a == &dev_attr_trigger_poison_list.attr)
-               if (!test_bit(CXL_POISON_ENABLED_LIST,
-                             mds->poison.enabled_cmds))
-                       return 0;
+       if (!mds ||
+           !test_bit(CXL_POISON_ENABLED_LIST, mds->poison.enabled_cmds))
+               return false;
+
+       return true;
+}
+
+static umode_t cxl_mem_visible(struct kobject *kobj, struct attribute *a, int n)
+{
+       if (a == &dev_attr_trigger_poison_list.attr &&
+           !cxl_poison_attr_visible(kobj, a))
+               return 0;
 
        return a->mode;
 }