From f9ebf984e7eb93a044f48c4089485051751face8 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Sun, 23 Jan 2022 16:55:06 -0800 Subject: [PATCH 123/217] cxl/list: Filter dports and targets by memdevs Trim dport / target information by the memdev filter. This is useful when validating connectivity and decoder programming. Link: https://lore.kernel.org/r/164298570626.3021641.18034728333613142555.stgit@dwillia2-desk3.amr.corp.intel.com Reported-by: Ben Widawsky Signed-off-by: Dan Williams Signed-off-by: Vishal Verma --- Documentation/cxl/lib/libcxl.txt | 1 + cxl/filter.c | 51 ++++++++++++++++++++++++++++++++ cxl/filter.h | 6 ++++ cxl/json.c | 51 +++++++++++++++++++++----------- cxl/json.h | 7 +++++ cxl/lib/libcxl.c | 5 ++++ cxl/lib/libcxl.sym | 1 + cxl/libcxl.h | 1 + 8 files changed, 105 insertions(+), 18 deletions(-) diff --git a/Documentation/cxl/lib/libcxl.txt b/Documentation/cxl/lib/libcxl.txt index 27eb29e..4392b47 100644 --- a/Documentation/cxl/lib/libcxl.txt +++ b/Documentation/cxl/lib/libcxl.txt @@ -221,6 +221,7 @@ const char *cxl_port_get_host(struct cxl_port *port); struct cxl_port *cxl_decoder_get_port(struct cxl_decoder *decoder); struct cxl_port *cxl_port_get_next_all(struct cxl_port *port, const struct cxl_port *top); +struct cxl_port *cxl_dport_get_port(struct cxl_dport *dport); #define cxl_port_foreach(parent, port) \ for (port = cxl_port_get_first(parent); port != NULL; \ diff --git a/cxl/filter.c b/cxl/filter.c index f6a23b7..925bf3a 100644 --- a/cxl/filter.c +++ b/cxl/filter.c @@ -435,6 +435,48 @@ util_cxl_decoder_filter_by_memdev(struct cxl_decoder *decoder, return NULL; } +struct cxl_target *util_cxl_target_filter_by_memdev(struct cxl_target *target, + const char *ident, + const char *serial) +{ + struct cxl_decoder *decoder = cxl_target_get_decoder(target); + struct cxl_ctx *ctx = cxl_decoder_get_ctx(decoder); + struct cxl_memdev *memdev; + + if (!ident && !serial) + return target; + + cxl_memdev_foreach(ctx, memdev) { + if (!util_cxl_memdev_filter(memdev, ident, serial)) + continue; + if (cxl_target_maps_memdev(target, memdev)) + return target; + } + + return NULL; +} + +struct cxl_dport *util_cxl_dport_filter_by_memdev(struct cxl_dport *dport, + const char *ident, + const char *serial) +{ + struct cxl_port *port = cxl_dport_get_port(dport); + struct cxl_ctx *ctx = cxl_port_get_ctx(port); + struct cxl_memdev *memdev; + + if (!ident && !serial) + return dport; + + cxl_memdev_foreach (ctx, memdev) { + if (!util_cxl_memdev_filter(memdev, ident, serial)) + continue; + if (cxl_dport_maps_memdev(dport, memdev)) + return dport; + } + + return NULL; +} + static bool __memdev_filter_by_decoder(struct cxl_memdev *memdev, struct cxl_port *port, const char *ident) { @@ -639,6 +681,9 @@ static void walk_decoders(struct cxl_port *port, struct cxl_filter_params *p, dbg(p, "decoder object allocation failure\n"); continue; } + util_cxl_targets_append_json(jdecoder, decoder, + p->memdev_filter, p->serial_filter, + flags); json_object_array_add(jdecoders, jdecoder); } } @@ -756,6 +801,9 @@ walk_child_ports(struct cxl_port *parent_port, struct cxl_filter_params *p, err(p, "%s: failed to list\n", devname); continue; } + util_cxl_dports_append_json(jport, port, + p->memdev_filter, + p->serial_filter, flags); json_object_array_add(jports, jport); jchildports = json_object_new_array(); if (!jchildports) { @@ -914,6 +962,9 @@ int cxl_filter_walk(struct cxl_ctx *ctx, struct cxl_filter_params *p) dbg(p, "bus object allocation failure\n"); continue; } + util_cxl_dports_append_json(jbus, port, + p->memdev_filter, + p->serial_filter, flags); json_object_array_add(jbuses, jbus); if (p->ports) { jchildports = json_object_new_array(); diff --git a/cxl/filter.h b/cxl/filter.h index 850df70..5deabb3 100644 --- a/cxl/filter.h +++ b/cxl/filter.h @@ -42,6 +42,12 @@ struct cxl_port *util_cxl_port_filter(struct cxl_port *port, const char *ident, enum cxl_port_filter_mode mode); struct cxl_endpoint *util_cxl_endpoint_filter(struct cxl_endpoint *endpoint, const char *__ident); +struct cxl_target *util_cxl_target_filter_by_memdev(struct cxl_target *target, + const char *ident, + const char *serial); +struct cxl_dport *util_cxl_dport_filter_by_memdev(struct cxl_dport *dport, + const char *ident, + const char *serial); int cxl_filter_walk(struct cxl_ctx *ctx, struct cxl_filter_params *param); bool cxl_filter_has(const char *needle, const char *__filter); #endif /* _CXL_UTIL_FILTER_H_ */ diff --git a/cxl/json.c b/cxl/json.c index 4fb5eec..f3b536e 100644 --- a/cxl/json.c +++ b/cxl/json.c @@ -8,6 +8,7 @@ #include #include +#include "filter.h" #include "json.h" static struct json_object *util_cxl_memdev_health_to_json( @@ -241,9 +242,9 @@ struct json_object *util_cxl_memdev_to_json(struct cxl_memdev *memdev, return jdev; } -static struct json_object *util_cxl_dports_to_json(struct json_object *jport, - struct cxl_port *port, - unsigned long flags) +void util_cxl_dports_append_json(struct json_object *jport, + struct cxl_port *port, const char *ident, + const char *serial, unsigned long flags) { struct json_object *jobj, *jdports; struct cxl_dport *dport; @@ -251,7 +252,7 @@ static struct json_object *util_cxl_dports_to_json(struct json_object *jport, val = cxl_port_get_nr_dports(port); if (!val || !(flags & UTIL_JSON_TARGETS)) - return jport; + return; jobj = json_object_new_int(val); if (jobj) @@ -259,12 +260,15 @@ static struct json_object *util_cxl_dports_to_json(struct json_object *jport, jdports = json_object_new_array(); if (!jdports) - return jport; + return; cxl_dport_foreach(port, dport) { struct json_object *jdport; const char *phys_node; + if (!util_cxl_dport_filter_by_memdev(dport, ident, serial)) + continue; + jdport = json_object_new_object(); if (!jdport) continue; @@ -289,8 +293,6 @@ static struct json_object *util_cxl_dports_to_json(struct json_object *jport, } json_object_object_add(jport, "dports", jdports); - - return jport; } struct json_object *util_cxl_bus_to_json(struct cxl_bus *bus, @@ -311,7 +313,7 @@ struct json_object *util_cxl_bus_to_json(struct cxl_bus *bus, if (jobj) json_object_object_add(jbus, "provider", jobj); - return util_cxl_dports_to_json(jbus, cxl_bus_get_port(bus), flags); + return jbus; } struct json_object *util_cxl_decoder_to_json(struct cxl_decoder *decoder, @@ -320,8 +322,6 @@ struct json_object *util_cxl_decoder_to_json(struct cxl_decoder *decoder, const char *devname = cxl_decoder_get_devname(decoder); struct cxl_port *port = cxl_decoder_get_port(decoder); struct json_object *jdecoder, *jobj; - struct json_object *jtargets; - struct cxl_target *target; u64 val; jdecoder = json_object_new_object(); @@ -375,9 +375,22 @@ struct json_object *util_cxl_decoder_to_json(struct cxl_decoder *decoder, jobj); } + return jdecoder; +} + +void util_cxl_targets_append_json(struct json_object *jdecoder, + struct cxl_decoder *decoder, + const char *ident, const char *serial, + unsigned long flags) +{ + struct cxl_port *port = cxl_decoder_get_port(decoder); + struct json_object *jobj, *jtargets; + struct cxl_target *target; + int val; + /* Endpoints don't have targets, they *are* targets */ if (cxl_port_is_endpoint(port)) - return jdecoder; + return; val = cxl_decoder_get_nr_targets(decoder); jobj = json_object_new_int(val); @@ -386,16 +399,21 @@ struct json_object *util_cxl_decoder_to_json(struct cxl_decoder *decoder, if (!(flags & UTIL_JSON_TARGETS) || !cxl_decoder_get_nr_targets(decoder)) - return jdecoder; + return; jtargets = json_object_new_array(); if (!jtargets) - return jdecoder; + return; cxl_target_foreach(decoder, target) { - struct json_object *jtarget = json_object_new_object(); + struct json_object *jtarget; const char *phys_node; + const char *devname; + + if (!util_cxl_target_filter_by_memdev(target, ident, serial)) + continue; + jtarget = json_object_new_object(); if (!jtarget) continue; @@ -425,9 +443,6 @@ struct json_object *util_cxl_decoder_to_json(struct cxl_decoder *decoder, } json_object_object_add(jdecoder, "targets", jtargets); - - return jdecoder; - } static struct json_object *__util_cxl_port_to_json(struct cxl_port *port, @@ -455,7 +470,7 @@ static struct json_object *__util_cxl_port_to_json(struct cxl_port *port, json_object_object_add(jport, "state", jobj); } - return util_cxl_dports_to_json(jport, port, flags); + return jport; } struct json_object *util_cxl_port_to_json(struct cxl_port *port, diff --git a/cxl/json.h b/cxl/json.h index fcca2e6..9a5a845 100644 --- a/cxl/json.h +++ b/cxl/json.h @@ -15,4 +15,11 @@ struct json_object *util_cxl_endpoint_to_json(struct cxl_endpoint *endpoint, unsigned long flags); struct json_object *util_cxl_decoder_to_json(struct cxl_decoder *decoder, unsigned long flags); +void util_cxl_targets_append_json(struct json_object *jdecoder, + struct cxl_decoder *decoder, + const char *ident, const char *serial, + unsigned long flags); +void util_cxl_dports_append_json(struct json_object *jport, + struct cxl_port *port, const char *ident, + const char *serial, unsigned long flags); #endif /* __CXL_UTIL_JSON_H__ */ diff --git a/cxl/lib/libcxl.c b/cxl/lib/libcxl.c index 1a7dccb..e0b443f 100644 --- a/cxl/lib/libcxl.c +++ b/cxl/lib/libcxl.c @@ -1527,6 +1527,11 @@ CXL_EXPORT int cxl_dport_get_id(struct cxl_dport *dport) return dport->id; } +CXL_EXPORT struct cxl_port *cxl_dport_get_port(struct cxl_dport *dport) +{ + return dport->port; +} + CXL_EXPORT bool cxl_dport_maps_memdev(struct cxl_dport *dport, struct cxl_memdev *memdev) { diff --git a/cxl/lib/libcxl.sym b/cxl/lib/libcxl.sym index 67c7fd5..e56a2bf 100644 --- a/cxl/lib/libcxl.sym +++ b/cxl/lib/libcxl.sym @@ -152,6 +152,7 @@ global: cxl_dport_get_devname; cxl_dport_get_physical_node; cxl_dport_get_id; + cxl_dport_get_port; cxl_port_get_dport_by_memdev; cxl_dport_maps_memdev; } LIBCXL_1; diff --git a/cxl/libcxl.h b/cxl/libcxl.h index 1aac396..3b2293b 100644 --- a/cxl/libcxl.h +++ b/cxl/libcxl.h @@ -113,6 +113,7 @@ struct cxl_dport *cxl_dport_get_first(struct cxl_port *port); struct cxl_dport *cxl_dport_get_next(struct cxl_dport *dport); const char *cxl_dport_get_devname(struct cxl_dport *dport); const char *cxl_dport_get_physical_node(struct cxl_dport *dport); +struct cxl_port *cxl_dport_get_port(struct cxl_dport *dport); int cxl_dport_get_id(struct cxl_dport *dport); bool cxl_dport_maps_memdev(struct cxl_dport *dport, struct cxl_memdev *memdev); struct cxl_dport *cxl_port_get_dport_by_memdev(struct cxl_port *port, -- 2.27.0