From patchwork Mon Jan 24 00:55:06 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dan Williams X-Patchwork-Id: 12721374 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 046C6C433F5 for ; Mon, 24 Jan 2022 00:55:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231628AbiAXAzH (ORCPT ); Sun, 23 Jan 2022 19:55:07 -0500 Received: from mga14.intel.com ([192.55.52.115]:46273 "EHLO mga14.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240677AbiAXAzG (ORCPT ); Sun, 23 Jan 2022 19:55:06 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1642985706; x=1674521706; h=subject:from:to:cc:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=3Tz+sC3aMaksL6nXTZI4KTBwoq4BpvovLwJRN2RUthw=; b=GTKhbp5xUo1MJ/HKuwM/9WzkbpO+GrnOpM9YE7Q/7sn9BJBi/udo2+Do Rha4eUViR7MIwfsqDjsBwtyY9l9qccRi1TIPsSW0k+T2ETIm/jtg9dJKd Ja+MGPTFX60/ypQ/N4pUk4rimHUQ9VwtmCbNG46wvajf55Vus4NbnGuli 3GO6OVCfaIz+HOQ0HiZ71r0jDej+KOETIzLKFUuUk+vESp7u0ZGBARGHP ERAoFuoNHd2NR/TuADigqxiM52GmGSz7eEuiiLmMj5DbUcqet5g3FhCJC 16irE9/vevxAr26+NjH49ia/GubDbzldkaMWb0B4ZRDh9mSvcNLfHIPZv w==; X-IronPort-AV: E=McAfee;i="6200,9189,10236"; a="246153193" X-IronPort-AV: E=Sophos;i="5.88,311,1635231600"; d="scan'208";a="246153193" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Jan 2022 16:55:06 -0800 X-IronPort-AV: E=Sophos;i="5.88,311,1635231600"; d="scan'208";a="596630905" Received: from dwillia2-desk3.jf.intel.com (HELO dwillia2-desk3.amr.corp.intel.com) ([10.54.39.25]) by fmsmga004-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Jan 2022 16:55:06 -0800 Subject: [ndctl PATCH 37/37] cxl/list: Filter dports and targets by memdevs From: Dan Williams To: linux-cxl@vger.kernel.org Cc: Ben Widawsky , vishal.l.verma@intel.com Date: Sun, 23 Jan 2022 16:55:06 -0800 Message-ID: <164298570626.3021641.18034728333613142555.stgit@dwillia2-desk3.amr.corp.intel.com> In-Reply-To: <164298550885.3021641.11210386002804544864.stgit@dwillia2-desk3.amr.corp.intel.com> References: <164298550885.3021641.11210386002804544864.stgit@dwillia2-desk3.amr.corp.intel.com> User-Agent: StGit/0.18-3-g996c MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-cxl@vger.kernel.org Trim dport / target information by the memdev filter. This is useful when validating connectivity and decoder programming. Reported-by: Ben Widawsky Signed-off-by: Dan Williams --- 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 27eb29ed2bae..4392b47e6ece 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 f6a23b7ff864..925bf3a1c62d 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 850df70da964..5deabb3d38fe 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 4fb5eec11077..f3b536e1d4fa 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 fcca2e6e9cb6..9a5a845eebbb 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 1a7dccb245d8..e0b443fb0aa4 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 67c7fd57c35c..e56a2bf96e22 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 1aac39618371..3b2293bbee84 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,