From eec8c953a840a1cbdca63352c64cec3e48e86afe Mon Sep 17 00:00:00 2001
From: Dan Williams <dan.j.williams@intel.com>
Date: Sun, 23 Jan 2022 16:53:39 -0800
Subject: [PATCH 107/217] cxl/list: Add 'host' entries for memdevs
For debugging CXL port connectivity issues it will be useful to have the
PCI device name for the memory expander in the 'memdev' listing.
Link: https://lore.kernel.org/r/164298561980.3021641.9636572507721689266.stgit@dwillia2-desk3.amr.corp.intel.com
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
---
Documentation/cxl/cxl-list.txt | 3 ++-
Documentation/cxl/lib/libcxl.txt | 4 ++++
cxl/json.c | 5 +++++
cxl/lib/libcxl.c | 24 ++++++++++++++++++++++++
cxl/lib/libcxl.sym | 1 +
cxl/lib/private.h | 1 +
cxl/libcxl.h | 1 +
7 files changed, 38 insertions(+), 1 deletion(-)
diff --git a/Documentation/cxl/cxl-list.txt b/Documentation/cxl/cxl-list.txt
index 30b6161..9c21ab7 100644
--- a/Documentation/cxl/cxl-list.txt
+++ b/Documentation/cxl/cxl-list.txt
@@ -43,7 +43,8 @@ EXAMPLE
"memdev":"mem0",
"pmem_size":268435456,
"ram_size":0,
- "serial":0
+ "serial":0,
+ "host":"0000:35:00.0"
}
]
diff --git a/Documentation/cxl/lib/libcxl.txt b/Documentation/cxl/lib/libcxl.txt
index e4b372d..91fd33e 100644
--- a/Documentation/cxl/lib/libcxl.txt
+++ b/Documentation/cxl/lib/libcxl.txt
@@ -40,6 +40,7 @@ kernel, or to send data or trigger kernel operations for a given device.
struct cxl_memdev *cxl_memdev_get_first(struct cxl_ctx *ctx);
struct cxl_memdev *cxl_memdev_get_next(struct cxl_memdev *memdev);
struct cxl_ctx *cxl_memdev_get_ctx(struct cxl_memdev *memdev);
+const char *cxl_memdev_get_host(struct cxl_memdev *memdev)
#define cxl_memdev_foreach(ctx, memdev) \
for (memdev = cxl_memdev_get_first(ctx); \
@@ -54,6 +55,9 @@ memory device commands, see the port, decoder, and endpoint APIs to
determine what if any CXL Memory Resources are reachable given a
specific memdev.
+The host of a memdev is the PCIe Endpoint device that registered its CXL
+capabilities with the Linux CXL core.
+
=== MEMDEV: Attributes
----
int cxl_memdev_get_id(struct cxl_memdev *memdev);
diff --git a/cxl/json.c b/cxl/json.c
index af3b4fe..1868686 100644
--- a/cxl/json.c
+++ b/cxl/json.c
@@ -219,6 +219,11 @@ struct json_object *util_cxl_memdev_to_json(struct cxl_memdev *memdev,
if (jobj)
json_object_object_add(jdev, "serial", jobj);
}
+
+ jobj = json_object_new_string(cxl_memdev_get_host(memdev));
+ if (jobj)
+ json_object_object_add(jdev, "host", jobj);
+
return jdev;
}
diff --git a/cxl/lib/libcxl.c b/cxl/lib/libcxl.c
index 5f48202..c4ddc7d 100644
--- a/cxl/lib/libcxl.c
+++ b/cxl/lib/libcxl.c
@@ -63,6 +63,7 @@ static void free_memdev(struct cxl_memdev *memdev, struct list_head *head)
free(memdev->firmware_version);
free(memdev->dev_buf);
free(memdev->dev_path);
+ free(memdev->host);
free(memdev);
}
@@ -297,6 +298,7 @@ static void *add_cxl_memdev(void *parent, int id, const char *cxlmem_base)
char *path = calloc(1, strlen(cxlmem_base) + 100);
struct cxl_ctx *ctx = parent;
struct cxl_memdev *memdev, *memdev_dup;
+ char *host, *rpath = NULL;
char buf[SYSFS_ATTR_SIZE];
struct stat st;
@@ -350,6 +352,22 @@ static void *add_cxl_memdev(void *parent, int id, const char *cxlmem_base)
if (!memdev->dev_path)
goto err_read;
+ rpath = realpath(cxlmem_base, NULL);
+ if (!rpath)
+ goto err_read;
+ host = strrchr(rpath, '/');
+ if (host) {
+ host[0] = '\0';
+ host = strrchr(rpath, '/');
+ }
+ if (!host)
+ goto err_read;
+ memdev->host = strdup(host + 1);
+ if (!memdev->host)
+ goto err_read;
+ free(rpath);
+ rpath = NULL;
+
sprintf(path, "%s/firmware_version", cxlmem_base);
if (sysfs_read_attr(ctx, path, buf) < 0)
goto err_read;
@@ -381,6 +399,7 @@ static void *add_cxl_memdev(void *parent, int id, const char *cxlmem_base)
free(memdev->dev_buf);
free(memdev->dev_path);
free(memdev);
+ free(rpath);
err_dev:
free(path);
return NULL;
@@ -431,6 +450,11 @@ CXL_EXPORT const char *cxl_memdev_get_devname(struct cxl_memdev *memdev)
return devpath_to_devname(memdev->dev_path);
}
+CXL_EXPORT const char *cxl_memdev_get_host(struct cxl_memdev *memdev)
+{
+ return memdev->host;
+}
+
CXL_EXPORT int cxl_memdev_get_major(struct cxl_memdev *memdev)
{
return memdev->major;
diff --git a/cxl/lib/libcxl.sym b/cxl/lib/libcxl.sym
index dc2863e..8f0688a 100644
--- a/cxl/lib/libcxl.sym
+++ b/cxl/lib/libcxl.sym
@@ -77,6 +77,7 @@ local:
LIBCXL_2 {
global:
cxl_memdev_get_serial;
+ cxl_memdev_get_host;
cxl_bus_get_first;
cxl_bus_get_next;
cxl_bus_get_provider;
diff --git a/cxl/lib/private.h b/cxl/lib/private.h
index cedd2f2..b097bdf 100644
--- a/cxl/lib/private.h
+++ b/cxl/lib/private.h
@@ -22,6 +22,7 @@ struct cxl_memdev {
int id, major, minor;
void *dev_buf;
size_t buf_len;
+ char *host;
char *dev_path;
char *firmware_version;
struct cxl_ctx *ctx;
diff --git a/cxl/libcxl.h b/cxl/libcxl.h
index a60777e..5487b55 100644
--- a/cxl/libcxl.h
+++ b/cxl/libcxl.h
@@ -38,6 +38,7 @@ struct cxl_memdev *cxl_memdev_get_next(struct cxl_memdev *memdev);
int cxl_memdev_get_id(struct cxl_memdev *memdev);
unsigned long long cxl_memdev_get_serial(struct cxl_memdev *memdev);
const char *cxl_memdev_get_devname(struct cxl_memdev *memdev);
+const char *cxl_memdev_get_host(struct cxl_memdev *memdev);
int cxl_memdev_get_major(struct cxl_memdev *memdev);
int cxl_memdev_get_minor(struct cxl_memdev *memdev);
struct cxl_ctx *cxl_memdev_get_ctx(struct cxl_memdev *memdev);
--
2.27.0