|
|
e0018b |
From 15cae420681c5e8efad2b4cbaf0470960e2eba52 Mon Sep 17 00:00:00 2001
|
|
|
e0018b |
From: Dan Williams <dan.j.williams@intel.com>
|
|
|
e0018b |
Date: Sun, 23 Jan 2022 16:54:55 -0800
|
|
|
e0018b |
Subject: [PATCH 121/217] cxl/list: Support filtering memdevs by ports
|
|
|
e0018b |
|
|
|
e0018b |
The ability to filter memdevs by decoders falls short when the decoder does
|
|
|
e0018b |
not have its target list programmed. So, introduce a by port filter to show
|
|
|
e0018b |
the potential memdevs that can be targeted by the decoder.
|
|
|
e0018b |
|
|
|
e0018b |
Link: https://lore.kernel.org/r/164298569568.3021641.888802471376117408.stgit@dwillia2-desk3.amr.corp.intel.com
|
|
|
e0018b |
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
|
|
|
e0018b |
Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
|
|
|
e0018b |
---
|
|
|
e0018b |
Documentation/cxl/cxl-list.txt | 3 +-
|
|
|
e0018b |
Documentation/cxl/lib/libcxl.txt | 7 ++++-
|
|
|
e0018b |
cxl/filter.c | 50 ++++++++++++++++++++++++++++++++
|
|
|
e0018b |
cxl/lib/libcxl.c | 23 +++++++++++++++
|
|
|
e0018b |
cxl/lib/libcxl.sym | 2 ++
|
|
|
e0018b |
cxl/libcxl.h | 3 ++
|
|
|
e0018b |
6 files changed, 86 insertions(+), 2 deletions(-)
|
|
|
e0018b |
|
|
|
e0018b |
diff --git a/Documentation/cxl/cxl-list.txt b/Documentation/cxl/cxl-list.txt
|
|
|
e0018b |
index 04e831e..90e6d9f 100644
|
|
|
e0018b |
--- a/Documentation/cxl/cxl-list.txt
|
|
|
e0018b |
+++ b/Documentation/cxl/cxl-list.txt
|
|
|
e0018b |
@@ -63,7 +63,8 @@ one or more memdevs. For example:
|
|
|
e0018b |
----
|
|
|
e0018b |
Additionally, when provisioning new interleave configurations it is
|
|
|
e0018b |
useful to know which memdevs can be referenced by a given decoder like a
|
|
|
e0018b |
-root decoder:
|
|
|
e0018b |
+root decoder, or mapped by a given port if the decoders are not
|
|
|
e0018b |
+configured.
|
|
|
e0018b |
----
|
|
|
e0018b |
# cxl list -Mu -d decoder0.0
|
|
|
e0018b |
{
|
|
|
e0018b |
diff --git a/Documentation/cxl/lib/libcxl.txt b/Documentation/cxl/lib/libcxl.txt
|
|
|
e0018b |
index 5ad3027..a0fcee9 100644
|
|
|
e0018b |
--- a/Documentation/cxl/lib/libcxl.txt
|
|
|
e0018b |
+++ b/Documentation/cxl/lib/libcxl.txt
|
|
|
e0018b |
@@ -276,11 +276,12 @@ CXL / PCIe host bridge.
|
|
|
e0018b |
----
|
|
|
e0018b |
struct cxl_dport *cxl_dport_get_first(struct cxl_port *port);
|
|
|
e0018b |
struct cxl_dport *cxl_dport_get_next(struct cxl_dport *dport);
|
|
|
e0018b |
+struct cxl_dport *cxl_port_get_dport_by_memdev(struct cxl_port *port,
|
|
|
e0018b |
+ struct cxl_memdev *memdev);
|
|
|
e0018b |
|
|
|
e0018b |
#define cxl_dport_foreach(port, dport) \
|
|
|
e0018b |
for (dport = cxl_dport_get_first(port); dport != NULL; \
|
|
|
e0018b |
dport = cxl_dport_get_next(dport))
|
|
|
e0018b |
-
|
|
|
e0018b |
----
|
|
|
e0018b |
|
|
|
e0018b |
===== DPORT: Attributes
|
|
|
e0018b |
@@ -288,12 +289,16 @@ struct cxl_dport *cxl_dport_get_next(struct cxl_dport *dport);
|
|
|
e0018b |
const char *cxl_dport_get_devname(struct cxl_dport *dport);
|
|
|
e0018b |
const char *cxl_dport_get_physical_node(struct cxl_dport *dport);
|
|
|
e0018b |
int cxl_dport_get_id(struct cxl_dport *dport);
|
|
|
e0018b |
+bool cxl_dport_maps_memdev(struct cxl_dport *dport, struct cxl_memdev *memdev);
|
|
|
e0018b |
----
|
|
|
e0018b |
The id of a dport is the hardware idenfifier used by an upstream port to
|
|
|
e0018b |
reference a downstream port. The physical node of a dport is only
|
|
|
e0018b |
available for platform firmware defined downstream ports and alias the
|
|
|
e0018b |
companion object, like a PCI host bridge, in the PCI device hierarchy.
|
|
|
e0018b |
|
|
|
e0018b |
+The cxl_dport_maps_memdev() helper checks if a dport is an ancestor of a
|
|
|
e0018b |
+given memdev.
|
|
|
e0018b |
+
|
|
|
e0018b |
ENDPOINTS
|
|
|
e0018b |
---------
|
|
|
e0018b |
CXL endpoint objects encapsulate the set of host-managed device-memory
|
|
|
e0018b |
diff --git a/cxl/filter.c b/cxl/filter.c
|
|
|
e0018b |
index c972545..c691edf 100644
|
|
|
e0018b |
--- a/cxl/filter.c
|
|
|
e0018b |
+++ b/cxl/filter.c
|
|
|
e0018b |
@@ -486,6 +486,53 @@ util_cxl_memdev_filter_by_decoder(struct cxl_memdev *memdev, const char *ident)
|
|
|
e0018b |
return NULL;
|
|
|
e0018b |
}
|
|
|
e0018b |
|
|
|
e0018b |
+static bool __memdev_filter_by_port(struct cxl_memdev *memdev,
|
|
|
e0018b |
+ struct cxl_port *port,
|
|
|
e0018b |
+ const char *port_ident)
|
|
|
e0018b |
+{
|
|
|
e0018b |
+ struct cxl_endpoint *endpoint;
|
|
|
e0018b |
+
|
|
|
e0018b |
+ if (util_cxl_port_filter(port, port_ident, CXL_PF_SINGLE) &&
|
|
|
e0018b |
+ cxl_port_get_dport_by_memdev(port, memdev))
|
|
|
e0018b |
+ return true;
|
|
|
e0018b |
+
|
|
|
e0018b |
+ cxl_endpoint_foreach(port, endpoint)
|
|
|
e0018b |
+ if (__memdev_filter_by_port(memdev,
|
|
|
e0018b |
+ cxl_endpoint_get_port(endpoint),
|
|
|
e0018b |
+ port_ident))
|
|
|
e0018b |
+ return true;
|
|
|
e0018b |
+ return false;
|
|
|
e0018b |
+}
|
|
|
e0018b |
+
|
|
|
e0018b |
+static struct cxl_memdev *
|
|
|
e0018b |
+util_cxl_memdev_filter_by_port(struct cxl_memdev *memdev, const char *bus_ident,
|
|
|
e0018b |
+ const char *port_ident)
|
|
|
e0018b |
+{
|
|
|
e0018b |
+ struct cxl_ctx *ctx = cxl_memdev_get_ctx(memdev);
|
|
|
e0018b |
+ struct cxl_bus *bus;
|
|
|
e0018b |
+
|
|
|
e0018b |
+ if (!bus_ident && !port_ident)
|
|
|
e0018b |
+ return memdev;
|
|
|
e0018b |
+
|
|
|
e0018b |
+ cxl_bus_foreach(ctx, bus) {
|
|
|
e0018b |
+ struct cxl_port *port, *top;
|
|
|
e0018b |
+
|
|
|
e0018b |
+ port = cxl_bus_get_port(bus);
|
|
|
e0018b |
+ if (util_cxl_bus_filter(bus, bus_ident))
|
|
|
e0018b |
+ if (__memdev_filter_by_port(memdev, port,
|
|
|
e0018b |
+ cxl_bus_get_devname(bus)))
|
|
|
e0018b |
+ return memdev;
|
|
|
e0018b |
+ if (__memdev_filter_by_port(memdev, port, port_ident))
|
|
|
e0018b |
+ return memdev;
|
|
|
e0018b |
+ top = port;
|
|
|
e0018b |
+ cxl_port_foreach_all(top, port)
|
|
|
e0018b |
+ if (__memdev_filter_by_port(memdev, port, port_ident))
|
|
|
e0018b |
+ return memdev;
|
|
|
e0018b |
+ }
|
|
|
e0018b |
+
|
|
|
e0018b |
+ return NULL;
|
|
|
e0018b |
+}
|
|
|
e0018b |
+
|
|
|
e0018b |
static unsigned long params_to_flags(struct cxl_filter_params *param)
|
|
|
e0018b |
{
|
|
|
e0018b |
unsigned long flags = 0;
|
|
|
e0018b |
@@ -647,6 +694,9 @@ static void walk_endpoints(struct cxl_port *port, struct cxl_filter_params *p,
|
|
|
e0018b |
if (!util_cxl_memdev_filter_by_decoder(
|
|
|
e0018b |
memdev, p->decoder_filter))
|
|
|
e0018b |
continue;
|
|
|
e0018b |
+ if (!util_cxl_memdev_filter_by_port(
|
|
|
e0018b |
+ memdev, p->bus_filter, p->port_filter))
|
|
|
e0018b |
+ continue;
|
|
|
e0018b |
if (!p->idle && !cxl_memdev_is_enabled(memdev))
|
|
|
e0018b |
continue;
|
|
|
e0018b |
jobj = util_cxl_memdev_to_json(memdev, flags);
|
|
|
e0018b |
diff --git a/cxl/lib/libcxl.c b/cxl/lib/libcxl.c
|
|
|
e0018b |
index 4ebb8b9..dcfc826 100644
|
|
|
e0018b |
--- a/cxl/lib/libcxl.c
|
|
|
e0018b |
+++ b/cxl/lib/libcxl.c
|
|
|
e0018b |
@@ -1452,6 +1452,29 @@ CXL_EXPORT int cxl_dport_get_id(struct cxl_dport *dport)
|
|
|
e0018b |
return dport->id;
|
|
|
e0018b |
}
|
|
|
e0018b |
|
|
|
e0018b |
+CXL_EXPORT bool cxl_dport_maps_memdev(struct cxl_dport *dport,
|
|
|
e0018b |
+ struct cxl_memdev *memdev)
|
|
|
e0018b |
+{
|
|
|
e0018b |
+ struct cxl_ctx *ctx = cxl_memdev_get_ctx(memdev);
|
|
|
e0018b |
+
|
|
|
e0018b |
+ dbg(ctx, "memdev: %s dport: %s\n", memdev->host_path, dport->dev_path);
|
|
|
e0018b |
+
|
|
|
e0018b |
+ if (dport->phys_path)
|
|
|
e0018b |
+ return !!strstr(memdev->host_path, dport->phys_path);
|
|
|
e0018b |
+ return !!strstr(memdev->host_path, dport->dev_path);
|
|
|
e0018b |
+}
|
|
|
e0018b |
+
|
|
|
e0018b |
+CXL_EXPORT struct cxl_dport *
|
|
|
e0018b |
+cxl_port_get_dport_by_memdev(struct cxl_port *port, struct cxl_memdev *memdev)
|
|
|
e0018b |
+{
|
|
|
e0018b |
+ struct cxl_dport *dport;
|
|
|
e0018b |
+
|
|
|
e0018b |
+ cxl_dport_foreach(port, dport)
|
|
|
e0018b |
+ if (cxl_dport_maps_memdev(dport, memdev))
|
|
|
e0018b |
+ return dport;
|
|
|
e0018b |
+ return NULL;
|
|
|
e0018b |
+}
|
|
|
e0018b |
+
|
|
|
e0018b |
static void *add_cxl_bus(void *parent, int id, const char *cxlbus_base)
|
|
|
e0018b |
{
|
|
|
e0018b |
const char *devname = devpath_to_devname(cxlbus_base);
|
|
|
e0018b |
diff --git a/cxl/lib/libcxl.sym b/cxl/lib/libcxl.sym
|
|
|
e0018b |
index 0190b13..2c8358e 100644
|
|
|
e0018b |
--- a/cxl/lib/libcxl.sym
|
|
|
e0018b |
+++ b/cxl/lib/libcxl.sym
|
|
|
e0018b |
@@ -149,4 +149,6 @@ global:
|
|
|
e0018b |
cxl_dport_get_devname;
|
|
|
e0018b |
cxl_dport_get_physical_node;
|
|
|
e0018b |
cxl_dport_get_id;
|
|
|
e0018b |
+ cxl_port_get_dport_by_memdev;
|
|
|
e0018b |
+ cxl_dport_maps_memdev;
|
|
|
e0018b |
} LIBCXL_1;
|
|
|
e0018b |
diff --git a/cxl/libcxl.h b/cxl/libcxl.h
|
|
|
e0018b |
index 874c381..c8d07bb 100644
|
|
|
e0018b |
--- a/cxl/libcxl.h
|
|
|
e0018b |
+++ b/cxl/libcxl.h
|
|
|
e0018b |
@@ -111,6 +111,9 @@ struct cxl_dport *cxl_dport_get_next(struct cxl_dport *dport);
|
|
|
e0018b |
const char *cxl_dport_get_devname(struct cxl_dport *dport);
|
|
|
e0018b |
const char *cxl_dport_get_physical_node(struct cxl_dport *dport);
|
|
|
e0018b |
int cxl_dport_get_id(struct cxl_dport *dport);
|
|
|
e0018b |
+bool cxl_dport_maps_memdev(struct cxl_dport *dport, struct cxl_memdev *memdev);
|
|
|
e0018b |
+struct cxl_dport *cxl_port_get_dport_by_memdev(struct cxl_port *port,
|
|
|
e0018b |
+ struct cxl_memdev *memdev);
|
|
|
e0018b |
|
|
|
e0018b |
#define cxl_dport_foreach(port, dport) \
|
|
|
e0018b |
for (dport = cxl_dport_get_first(port); dport != NULL; \
|
|
|
e0018b |
--
|
|
|
e0018b |
2.27.0
|
|
|
e0018b |
|