diff mbox series

[ndctl,1/2] cxl-list: add `parent_dport` to cxl_port/memdev objects

Message ID 20221220182510.2734032-2-fan.ni@samsung.com
State New, archived
Headers show
Series cxl-list: Construct CXL topology graph images | expand

Commit Message

Fan Ni Dec. 20, 2022, 6:26 p.m. UTC
The parent_dport attribute reprents the downstream port that the current
device (cxl_port/cxl_memdev) is attached to. It will help to track the
topology when plotting the cxl graph

Signed-off-by: Fan Ni <fan.ni@samsung.com>
---
 cxl/json.c         |  8 ++++++++
 cxl/lib/libcxl.c   | 39 +++++++++++++++++++++++++++++++++++++++
 cxl/lib/libcxl.sym |  6 ++++++
 cxl/lib/private.h  |  1 +
 cxl/libcxl.h       |  2 ++
 5 files changed, 56 insertions(+)
diff mbox series

Patch

diff --git a/cxl/json.c b/cxl/json.c
index 63c1751..ac1b0b5 100644
--- a/cxl/json.c
+++ b/cxl/json.c
@@ -348,6 +348,10 @@  struct json_object *util_cxl_memdev_to_json(struct cxl_memdev *memdev,
 	if (jobj)
 		json_object_object_add(jdev, "host", jobj);
 
+	jobj = json_object_new_string(cxl_memdev_get_parent_dport(memdev));
+	if (jobj)
+		json_object_object_add(jdev, "parent_dport", jobj);
+
 	if (!cxl_memdev_is_enabled(memdev)) {
 		jobj = json_object_new_string("disabled");
 		if (jobj)
@@ -769,6 +773,10 @@  static struct json_object *__util_cxl_port_to_json(struct cxl_port *port,
 	if (jobj)
 		json_object_object_add(jport, "host", jobj);
 
+	jobj = json_object_new_string(cxl_port_get_parent_dport(port));
+	if (jobj)
+		json_object_object_add(jport, "parent_dport", jobj);
+
 	jobj = json_object_new_int(cxl_port_get_depth(port));
 	if (jobj)
 		json_object_object_add(jport, "depth", jobj);
diff --git a/cxl/lib/libcxl.c b/cxl/lib/libcxl.c
index e8c5d44..27ffee0 100644
--- a/cxl/lib/libcxl.c
+++ b/cxl/lib/libcxl.c
@@ -1267,6 +1267,16 @@  CXL_EXPORT const char *cxl_memdev_get_firmware_verison(struct cxl_memdev *memdev
 	return memdev->firmware_version;
 }
 
+CXL_EXPORT const char *cxl_memdev_get_parent_dport(struct cxl_memdev *memdev)
+{
+	struct cxl_port *port = cxl_endpoint_get_port(memdev->endpoint);
+
+	if (port)
+		return cxl_port_get_parent_dport(port);
+
+	return NULL;
+}
+
 static void bus_invalidate(struct cxl_bus *bus)
 {
 	struct cxl_ctx *ctx = cxl_bus_get_ctx(bus);
@@ -1447,6 +1457,24 @@  CXL_EXPORT int cxl_memdev_nvdimm_bridge_active(struct cxl_memdev *memdev)
 	return is_enabled(path);
 }
 
+static struct cxl_dport *cxl_port_find_parent_dport(struct cxl_port *port,
+			struct cxl_port *parent_port)
+{
+	struct cxl_dport *dport;
+
+	if (parent_port && parent_port->nr_dports) {
+		cxl_dport_foreach(parent_port, dport) {
+			/* HB ACPI0016 can have only one dport and being itself */
+			if (!strcmp(port->uport, dport->dev_path))
+				return NULL;
+			if (strstr(port->uport, dport->dev_path))
+				return dport;
+		}
+	}
+
+	return NULL;
+}
+
 static int cxl_port_init(struct cxl_port *port, struct cxl_port *parent_port,
 			 enum cxl_port_type type, struct cxl_ctx *ctx, int id,
 			 const char *cxlport_base)
@@ -1486,6 +1514,8 @@  static int cxl_port_init(struct cxl_port *port, struct cxl_port *parent_port,
 	if (!port->uport)
 		goto err;
 
+	port->parent_dport = cxl_port_find_parent_dport(port, parent_port);
+
 	sprintf(path, "%s/modalias", cxlport_base);
 	if (sysfs_read_attr(ctx, path, buf) == 0)
 		port->module = util_modalias_to_module(ctx, buf);
@@ -2404,6 +2434,15 @@  CXL_EXPORT struct cxl_port *cxl_port_get_parent(struct cxl_port *port)
 	return port->parent;
 }
 
+CXL_EXPORT const char *cxl_port_get_parent_dport(struct cxl_port *port)
+{
+	if (port->parent_dport)
+		return devpath_to_devname(port->parent_dport->dev_path);
+	else if (port->parent)
+		return devpath_to_devname(port->parent->uport);
+	return NULL;
+}
+
 CXL_EXPORT bool cxl_port_is_root(struct cxl_port *port)
 {
 	return port->type == CXL_PORT_ROOT;
diff --git a/cxl/lib/libcxl.sym b/cxl/lib/libcxl.sym
index 8bb91e0..33f3bba 100644
--- a/cxl/lib/libcxl.sym
+++ b/cxl/lib/libcxl.sym
@@ -217,3 +217,9 @@  global:
 	cxl_decoder_get_max_available_extent;
 	cxl_decoder_get_region;
 } LIBCXL_2;
+
+LIBCXL_4 {
+global:
+	cxl_memdev_get_parent_dport;
+	cxl_port_get_parent_dport;
+}LIBCXL_3;
diff --git a/cxl/lib/private.h b/cxl/lib/private.h
index 437eade..ee7d769 100644
--- a/cxl/lib/private.h
+++ b/cxl/lib/private.h
@@ -71,6 +71,7 @@  struct cxl_port {
 	struct cxl_bus *bus;
 	enum cxl_port_type type;
 	struct cxl_port *parent;
+	struct cxl_dport *parent_dport;
 	struct kmod_module *module;
 	struct list_node list;
 	struct list_head child_ports;
diff --git a/cxl/libcxl.h b/cxl/libcxl.h
index 9fe4e99..588ad00 100644
--- a/cxl/libcxl.h
+++ b/cxl/libcxl.h
@@ -34,6 +34,7 @@  void cxl_set_private_data(struct cxl_ctx *ctx, void *data);
 void *cxl_get_private_data(struct cxl_ctx *ctx);
 
 struct cxl_memdev;
+const char *cxl_memdev_get_parent_dport(struct cxl_memdev *memdev);
 struct cxl_memdev *cxl_memdev_get_first(struct cxl_ctx *ctx);
 struct cxl_memdev *cxl_memdev_get_next(struct cxl_memdev *memdev);
 int cxl_memdev_get_id(struct cxl_memdev *memdev);
@@ -81,6 +82,7 @@  int cxl_bus_disable_invalidate(struct cxl_bus *bus);
 	     bus = cxl_bus_get_next(bus))
 
 struct cxl_port;
+const char *cxl_port_get_parent_dport(struct cxl_port *port);
 struct cxl_port *cxl_port_get_first(struct cxl_port *parent);
 struct cxl_port *cxl_port_get_next(struct cxl_port *port);
 const char *cxl_port_get_devname(struct cxl_port *port);