From eec8c953a840a1cbdca63352c64cec3e48e86afe Mon Sep 17 00:00:00 2001 From: Dan Williams 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 Signed-off-by: Vishal Verma --- 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