anitazha / rpms / ndctl

Forked from rpms/ndctl a year ago
Clone

Blame 0120-cxl-list-Support-filtering-memdevs-by-decoders.patch

Jeff Moyer 2c91dc
From aa022d33418021da81a51bc9656931c54043b10b Mon Sep 17 00:00:00 2001
Jeff Moyer 2c91dc
From: Dan Williams <dan.j.williams@intel.com>
Jeff Moyer 2c91dc
Date: Sun, 23 Jan 2022 16:54:50 -0800
Jeff Moyer 2c91dc
Subject: [PATCH 120/217] cxl/list: Support filtering memdevs by decoders
Jeff Moyer 2c91dc
Jeff Moyer 2c91dc
In order to filter memdevs by decoders all the ports in the hierarchy need
Jeff Moyer 2c91dc
to be iterated, so introduce cxl_port_foreach_all() that starts at the bus
Jeff Moyer 2c91dc
and does a depth first iteration of all the descendant ports.
Jeff Moyer 2c91dc
Jeff Moyer 2c91dc
Link: https://lore.kernel.org/r/164298569017.3021641.15558596583530530035.stgit@dwillia2-desk3.amr.corp.intel.com
Jeff Moyer 2c91dc
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Jeff Moyer 2c91dc
Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
Jeff Moyer 2c91dc
---
Jeff Moyer 2c91dc
 .clang-format                    |  1 +
Jeff Moyer 2c91dc
 Documentation/cxl/cxl-list.txt   | 13 +++++++++
Jeff Moyer 2c91dc
 Documentation/cxl/lib/libcxl.txt | 11 ++++++++
Jeff Moyer 2c91dc
 cxl/filter.c                     | 48 ++++++++++++++++++++++++++++++++
Jeff Moyer 2c91dc
 cxl/lib/libcxl.c                 | 13 +++++++++
Jeff Moyer 2c91dc
 cxl/libcxl.h                     |  6 ++++
Jeff Moyer 2c91dc
 6 files changed, 92 insertions(+)
Jeff Moyer 2c91dc
Jeff Moyer 2c91dc
diff --git a/.clang-format b/.clang-format
Jeff Moyer 2c91dc
index c753487..6aabcb6 100644
Jeff Moyer 2c91dc
--- a/.clang-format
Jeff Moyer 2c91dc
+++ b/.clang-format
Jeff Moyer 2c91dc
@@ -84,6 +84,7 @@ ForEachMacros:
Jeff Moyer 2c91dc
   - 'cxl_target_foreach'
Jeff Moyer 2c91dc
   - 'cxl_dport_foreach'
Jeff Moyer 2c91dc
   - 'cxl_endpoint_foreach'
Jeff Moyer 2c91dc
+  - 'cxl_port_foreach_all'
Jeff Moyer 2c91dc
   - 'daxctl_dev_foreach'
Jeff Moyer 2c91dc
   - 'daxctl_mapping_foreach'
Jeff Moyer 2c91dc
   - 'daxctl_region_foreach'
Jeff Moyer 2c91dc
diff --git a/Documentation/cxl/cxl-list.txt b/Documentation/cxl/cxl-list.txt
Jeff Moyer 2c91dc
index e1299d9..04e831e 100644
Jeff Moyer 2c91dc
--- a/Documentation/cxl/cxl-list.txt
Jeff Moyer 2c91dc
+++ b/Documentation/cxl/cxl-list.txt
Jeff Moyer 2c91dc
@@ -61,6 +61,19 @@ one or more memdevs. For example:
Jeff Moyer 2c91dc
   }
Jeff Moyer 2c91dc
 ]
Jeff Moyer 2c91dc
 ----
Jeff Moyer 2c91dc
+Additionally, when provisioning new interleave configurations it is
Jeff Moyer 2c91dc
+useful to know which memdevs can be referenced by a given decoder like a
Jeff Moyer 2c91dc
+root decoder:
Jeff Moyer 2c91dc
+----
Jeff Moyer 2c91dc
+# cxl list -Mu -d decoder0.0
Jeff Moyer 2c91dc
+{
Jeff Moyer 2c91dc
+  "memdev":"mem0",
Jeff Moyer 2c91dc
+  "pmem_size":"256.00 MiB (268.44 MB)",
Jeff Moyer 2c91dc
+  "ram_size":0,
Jeff Moyer 2c91dc
+  "serial":"0",
Jeff Moyer 2c91dc
+  "host":"0000:35:00.0"
Jeff Moyer 2c91dc
+}
Jeff Moyer 2c91dc
+----
Jeff Moyer 2c91dc
 
Jeff Moyer 2c91dc
 The --human option in addition to reformatting some fields to more human
Jeff Moyer 2c91dc
 friendly strings also unwraps the array to reduce the number of lines of
Jeff Moyer 2c91dc
diff --git a/Documentation/cxl/lib/libcxl.txt b/Documentation/cxl/lib/libcxl.txt
Jeff Moyer 2c91dc
index 2e8570d..5ad3027 100644
Jeff Moyer 2c91dc
--- a/Documentation/cxl/lib/libcxl.txt
Jeff Moyer 2c91dc
+++ b/Documentation/cxl/lib/libcxl.txt
Jeff Moyer 2c91dc
@@ -219,10 +219,18 @@ struct cxl_port *cxl_port_get_parent(struct cxl_port *port);
Jeff Moyer 2c91dc
 struct cxl_ctx *cxl_port_get_ctx(struct cxl_port *port);
Jeff Moyer 2c91dc
 const char *cxl_port_get_host(struct cxl_port *port);
Jeff Moyer 2c91dc
 struct cxl_port *cxl_decoder_get_port(struct cxl_decoder *decoder);
Jeff Moyer 2c91dc
+struct cxl_port *cxl_port_get_next_all(struct cxl_port *port,
Jeff Moyer 2c91dc
+                                       const struct cxl_port *top);
Jeff Moyer 2c91dc
 
Jeff Moyer 2c91dc
 #define cxl_port_foreach(parent, port)                                      \
Jeff Moyer 2c91dc
        for (port = cxl_port_get_first(parent); port != NULL;                \
Jeff Moyer 2c91dc
             port = cxl_port_get_next(port))
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+#define cxl_port_foreach_all(top, port)                                        \
Jeff Moyer 2c91dc
+       for (port = cxl_port_get_first(top); port != NULL;                     \
Jeff Moyer 2c91dc
+            port = cxl_port_get_next_all(port, top))
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
 ----
Jeff Moyer 2c91dc
 A bus object encapsulates a CXL port object. Use cxl_bus_get_port() to
Jeff Moyer 2c91dc
 use generic port APIs on root objects.
Jeff Moyer 2c91dc
@@ -236,6 +244,9 @@ that hierarchy via cxl_port_get_bus().
Jeff Moyer 2c91dc
 The host of a port is the corresponding device name of the PCIe Root
Jeff Moyer 2c91dc
 Port, or Switch Upstream Port with CXL capabilities.
Jeff Moyer 2c91dc
 
Jeff Moyer 2c91dc
+The cxl_port_foreach_all() helper does a depth first iteration of all
Jeff Moyer 2c91dc
+ports beneath the 'top' port argument.
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
 === PORT: Attributes
Jeff Moyer 2c91dc
 ----
Jeff Moyer 2c91dc
 const char *cxl_port_get_devname(struct cxl_port *port);
Jeff Moyer 2c91dc
diff --git a/cxl/filter.c b/cxl/filter.c
Jeff Moyer 2c91dc
index 05ede91..c972545 100644
Jeff Moyer 2c91dc
--- a/cxl/filter.c
Jeff Moyer 2c91dc
+++ b/cxl/filter.c
Jeff Moyer 2c91dc
@@ -441,6 +441,51 @@ util_cxl_decoder_filter_by_memdev(struct cxl_decoder *decoder,
Jeff Moyer 2c91dc
 	return NULL;
Jeff Moyer 2c91dc
 }
Jeff Moyer 2c91dc
 
Jeff Moyer 2c91dc
+static bool __memdev_filter_by_decoder(struct cxl_memdev *memdev,
Jeff Moyer 2c91dc
+				       struct cxl_port *port, const char *ident)
Jeff Moyer 2c91dc
+{
Jeff Moyer 2c91dc
+	struct cxl_decoder *decoder;
Jeff Moyer 2c91dc
+	struct cxl_endpoint *endpoint;
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+	cxl_decoder_foreach(port, decoder) {
Jeff Moyer 2c91dc
+		if (!util_cxl_decoder_filter(decoder, ident))
Jeff Moyer 2c91dc
+			continue;
Jeff Moyer 2c91dc
+		if (cxl_decoder_get_target_by_memdev(decoder, memdev))
Jeff Moyer 2c91dc
+			return true;
Jeff Moyer 2c91dc
+	}
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+	cxl_endpoint_foreach(port, endpoint)
Jeff Moyer 2c91dc
+		if (__memdev_filter_by_decoder(
Jeff Moyer 2c91dc
+			    memdev, cxl_endpoint_get_port(endpoint), ident))
Jeff Moyer 2c91dc
+			return true;
Jeff Moyer 2c91dc
+	return false;
Jeff Moyer 2c91dc
+}
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+static struct cxl_memdev *
Jeff Moyer 2c91dc
+util_cxl_memdev_filter_by_decoder(struct cxl_memdev *memdev, const char *ident)
Jeff Moyer 2c91dc
+{
Jeff Moyer 2c91dc
+	struct cxl_ctx *ctx = cxl_memdev_get_ctx(memdev);
Jeff Moyer 2c91dc
+	struct cxl_bus *bus;
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+	if (!ident)
Jeff Moyer 2c91dc
+		return memdev;
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+	cxl_bus_foreach(ctx, bus) {
Jeff Moyer 2c91dc
+		struct cxl_port *port, *top;
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+		port = cxl_bus_get_port(bus);
Jeff Moyer 2c91dc
+		if (__memdev_filter_by_decoder(memdev, port, ident))
Jeff Moyer 2c91dc
+			return memdev;
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+		top = port;
Jeff Moyer 2c91dc
+		cxl_port_foreach_all(top, port)
Jeff Moyer 2c91dc
+			if (__memdev_filter_by_decoder(memdev, port, ident))
Jeff Moyer 2c91dc
+				return memdev;
Jeff Moyer 2c91dc
+	}
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+	return NULL;
Jeff Moyer 2c91dc
+}
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
 static unsigned long params_to_flags(struct cxl_filter_params *param)
Jeff Moyer 2c91dc
 {
Jeff Moyer 2c91dc
 	unsigned long flags = 0;
Jeff Moyer 2c91dc
@@ -599,6 +644,9 @@ static void walk_endpoints(struct cxl_port *port, struct cxl_filter_params *p,
Jeff Moyer 2c91dc
 			if (!util_cxl_memdev_filter(memdev, p->memdev_filter,
Jeff Moyer 2c91dc
 						    p->serial_filter))
Jeff Moyer 2c91dc
 				continue;
Jeff Moyer 2c91dc
+			if (!util_cxl_memdev_filter_by_decoder(
Jeff Moyer 2c91dc
+				    memdev, p->decoder_filter))
Jeff Moyer 2c91dc
+				continue;
Jeff Moyer 2c91dc
 			if (!p->idle && !cxl_memdev_is_enabled(memdev))
Jeff Moyer 2c91dc
 				continue;
Jeff Moyer 2c91dc
 			jobj = util_cxl_memdev_to_json(memdev, flags);
Jeff Moyer 2c91dc
diff --git a/cxl/lib/libcxl.c b/cxl/lib/libcxl.c
Jeff Moyer 2c91dc
index d7a3f10..4ebb8b9 100644
Jeff Moyer 2c91dc
--- a/cxl/lib/libcxl.c
Jeff Moyer 2c91dc
+++ b/cxl/lib/libcxl.c
Jeff Moyer 2c91dc
@@ -1257,6 +1257,19 @@ CXL_EXPORT struct cxl_port *cxl_port_get_next(struct cxl_port *port)
Jeff Moyer 2c91dc
 	return list_next(&parent_port->child_ports, port, list);
Jeff Moyer 2c91dc
 }
Jeff Moyer 2c91dc
 
Jeff Moyer 2c91dc
+CXL_EXPORT struct cxl_port *cxl_port_get_next_all(struct cxl_port *port,
Jeff Moyer 2c91dc
+						  const struct cxl_port *top)
Jeff Moyer 2c91dc
+{
Jeff Moyer 2c91dc
+	struct cxl_port *child, *iter = port;
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+	child = cxl_port_get_first(iter);
Jeff Moyer 2c91dc
+	if (child)
Jeff Moyer 2c91dc
+		return child;
Jeff Moyer 2c91dc
+	while (!cxl_port_get_next(iter) && iter->parent && iter->parent != top)
Jeff Moyer 2c91dc
+		iter = iter->parent;
Jeff Moyer 2c91dc
+	return cxl_port_get_next(iter);
Jeff Moyer 2c91dc
+}
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
 CXL_EXPORT const char *cxl_port_get_devname(struct cxl_port *port)
Jeff Moyer 2c91dc
 {
Jeff Moyer 2c91dc
 	return devpath_to_devname(port->dev_path);
Jeff Moyer 2c91dc
diff --git a/cxl/libcxl.h b/cxl/libcxl.h
Jeff Moyer 2c91dc
index 07f4a31..874c381 100644
Jeff Moyer 2c91dc
--- a/cxl/libcxl.h
Jeff Moyer 2c91dc
+++ b/cxl/libcxl.h
Jeff Moyer 2c91dc
@@ -94,11 +94,17 @@ struct cxl_bus *cxl_port_get_bus(struct cxl_port *port);
Jeff Moyer 2c91dc
 const char *cxl_port_get_host(struct cxl_port *port);
Jeff Moyer 2c91dc
 bool cxl_port_hosts_memdev(struct cxl_port *port, struct cxl_memdev *memdev);
Jeff Moyer 2c91dc
 int cxl_port_get_nr_dports(struct cxl_port *port);
Jeff Moyer 2c91dc
+struct cxl_port *cxl_port_get_next_all(struct cxl_port *port,
Jeff Moyer 2c91dc
+				       const struct cxl_port *top);
Jeff Moyer 2c91dc
 
Jeff Moyer 2c91dc
 #define cxl_port_foreach(parent, port)                                         \
Jeff Moyer 2c91dc
 	for (port = cxl_port_get_first(parent); port != NULL;                  \
Jeff Moyer 2c91dc
 	     port = cxl_port_get_next(port))
Jeff Moyer 2c91dc
 
Jeff Moyer 2c91dc
+#define cxl_port_foreach_all(top, port)                                        \
Jeff Moyer 2c91dc
+	for (port = cxl_port_get_first(top); port != NULL;                     \
Jeff Moyer 2c91dc
+	     port = cxl_port_get_next_all(port, top))
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
 struct cxl_dport;
Jeff Moyer 2c91dc
 struct cxl_dport *cxl_dport_get_first(struct cxl_port *port);
Jeff Moyer 2c91dc
 struct cxl_dport *cxl_dport_get_next(struct cxl_dport *dport);
Jeff Moyer 2c91dc
-- 
Jeff Moyer 2c91dc
2.27.0
Jeff Moyer 2c91dc