[PATCH] cxl/core: Create einj_types when EINJ becomes available

From: Yongxin Yang

Date: Wed Oct 28 2026 - 01:54:58 EST


From: Yang Yongxin <yangyongxin@xxxxxxxxxx>

The einj_types file under the CXL debugfs directory is never created.

cxl_core_init() runs at subsys_initcall level, while EINJ registers itself
from einj_init() at module_init level. When cxl_core_init() evaluates
einj_cxl_is_initialized() the EINJ driver has not been initialized yet, so
the value is always false and the debugfs_create_file("einj_types") call
below it is never reached. Users have no way to discover which CXL error
types the platform supports from debugfs.

Create the file lazily, from the first place where EINJ is known to be up.
Note that this is a partial fix: if no injectable dport is ever added, the
file still does not appear. Fixing the initcall ordering itself would
require moving cxl_core_init() after EINJ is probed, which risks the CXL
bus registration order, so it is left out of scope here.

Fixes: 8039804cfa73 ("cxl/core: Add CXL EINJ debugfs files")
Cc: <stable@xxxxxxxxxxxxxxx>
Signed-off-by: Yang Yongxin <yangyongxin@xxxxxxxxxx>
---
drivers/cxl/core/port.c | 29 +++++++++++++++++++++++------
1 file changed, 23 insertions(+), 6 deletions(-)

diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c
index 625e4aa427db..7de08063469f 100644
--- a/drivers/cxl/core/port.c
+++ b/drivers/cxl/core/port.c
@@ -802,6 +802,27 @@ static int cxl_dport_setup_regs(struct device *host, struct cxl_dport *dport,

DEFINE_SHOW_ATTRIBUTE(einj_cxl_available_error_type);

+static struct dentry *cxl_debugfs;
+static struct dentry *einj_types_dentry;
+
+/*
+ * einj_types cannot be created from cxl_core_init(): that runs at
+ * subsys_initcall level, before einj_init() has set einj_initialized.
+ * Create it lazily, from the first place where EINJ is known to be up.
+ */
+static void cxl_einj_debugfs_add_types(void)
+{
+ if (einj_types_dentry)
+ return;
+
+ if (!einj_cxl_is_initialized())
+ return;
+
+ einj_types_dentry = debugfs_create_file("einj_types", 0400, cxl_debugfs,
+ NULL,
+ &einj_cxl_available_error_type_fops);
+}
+
static int cxl_einj_inject(void *data, u64 type)
{
struct cxl_dport *dport = data;
@@ -819,6 +840,8 @@ static void cxl_debugfs_create_dport_dir(struct cxl_dport *dport)
struct cxl_port *parent = parent_port_of(dport->port);
struct dentry *dir;

+ cxl_einj_debugfs_add_types();
+
if (!einj_cxl_is_initialized())
return;

@@ -2501,8 +2524,6 @@ const struct bus_type cxl_bus_type = {
};
EXPORT_SYMBOL_NS_GPL(cxl_bus_type, "CXL");

-static struct dentry *cxl_debugfs;
-
struct dentry *cxl_debugfs_create_dir(const char *dir)
{
return debugfs_create_dir(dir, cxl_debugfs);
@@ -2515,10 +2536,6 @@ static __init int cxl_core_init(void)

cxl_debugfs = debugfs_create_dir("cxl", NULL);

- if (einj_cxl_is_initialized())
- debugfs_create_file("einj_types", 0400, cxl_debugfs, NULL,
- &einj_cxl_available_error_type_fops);
-
cxl_mbox_init();

rc = cxl_memdev_init();
--
2.25.1