All of lore.kernel.org
 help / color / mirror / Atom feed
* [ndctl PATCH 00/10] CXL topology unit test
@ 2022-04-28 22:10 Dan Williams
  2022-04-28 22:10 ` [ndctl PATCH 01/10] build: Move utility helpers to libutil.a Dan Williams
                   ` (9 more replies)
  0 siblings, 10 replies; 11+ messages in thread
From: Dan Williams @ 2022-04-28 22:10 UTC (permalink / raw)
  To: vishal.l.verma; +Cc: Luis Chamberlain, linux-cxl, nvdimm

Vishal,

Here is a series that adds a unit test for CXL bus operations around
port discovery and memory device enable/disable events. Along the way it
adds some helper commands ('cxl disable-bus') and calling convention
cleanups ('cxl list -p $port'). Some other miscellaneous fixups and
cleanups are thrown in for good measure.

---

Dan Williams (10):
      build: Move utility helpers to libutil.a
      util: Use SZ_ size macros in display size
      util: Pretty print terabytes
      cxl/port: Fix disable-port man page
      cxl/bus: Add bus disable support
      cxl/list: Auto-enable 'single' mode for port listings
      cxl/memdev: Fix bus_invalidate() crash
      cxl/list: Add support for filtering by host identifiers
      cxl/port: Relax port identifier validation
      cxl/test: Add topology enumeration and hotplug test


 Documentation/cxl/cxl-disable-bus.txt  |   37 +++++++
 Documentation/cxl/cxl-disable-port.txt |    6 -
 Documentation/cxl/lib/libcxl.txt       |   12 ++
 Documentation/cxl/meson.build          |    1 
 cxl/builtin.h                          |    1 
 cxl/bus.c                              |  159 +++++++++++++++++++++++++++++++
 cxl/cxl.c                              |    1 
 cxl/filter.c                           |   12 ++
 cxl/filter.h                           |    1 
 cxl/lib/libcxl.c                       |   18 +++
 cxl/lib/libcxl.sym                     |    1 
 cxl/libcxl.h                           |    1 
 cxl/list.c                             |    1 
 cxl/meson.build                        |    3 -
 cxl/port.c                             |   30 +-----
 daxctl/meson.build                     |    1 
 ndctl/meson.build                      |    2 
 test/common                            |   12 ++
 test/cxl-topology.sh                   |  166 ++++++++++++++++++++++++++++++++
 test/meson.build                       |    2 
 util/json.c                            |   26 ++++-
 util/meson.build                       |    2 
 22 files changed, 448 insertions(+), 47 deletions(-)
 create mode 100644 Documentation/cxl/cxl-disable-bus.txt
 create mode 100644 cxl/bus.c
 create mode 100644 test/cxl-topology.sh

base-commit: 97031db9300654260bc2afb45b3600ac01beaeba

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [ndctl PATCH 01/10] build: Move utility helpers to libutil.a
  2022-04-28 22:10 [ndctl PATCH 00/10] CXL topology unit test Dan Williams
@ 2022-04-28 22:10 ` Dan Williams
  2022-04-28 22:10 ` [ndctl PATCH 02/10] util: Use SZ_ size macros in display size Dan Williams
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Dan Williams @ 2022-04-28 22:10 UTC (permalink / raw)
  To: vishal.l.verma; +Cc: linux-cxl, nvdimm

Stop listing util/json.c and util/log.c per command, just add them to
the common libutil.a object.

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 cxl/meson.build    |    2 --
 daxctl/meson.build |    1 -
 ndctl/meson.build  |    2 --
 util/meson.build   |    2 ++
 4 files changed, 2 insertions(+), 5 deletions(-)

diff --git a/cxl/meson.build b/cxl/meson.build
index 87cfea73e40b..671c8e1626ef 100644
--- a/cxl/meson.build
+++ b/cxl/meson.build
@@ -3,8 +3,6 @@ cxl_src = [
   'list.c',
   'port.c',
   'memdev.c',
-  '../util/json.c',
-  '../util/log.c',
   'json.c',
   'filter.c',
 ]
diff --git a/daxctl/meson.build b/daxctl/meson.build
index 8474d02f2c0d..8f27dd71b965 100644
--- a/daxctl/meson.build
+++ b/daxctl/meson.build
@@ -4,7 +4,6 @@ daxctl_src = [
   'list.c',
   'migrate.c',
   'device.c',
-  '../util/json.c',
   'json.c',
   'filter.c',
 ]
diff --git a/ndctl/meson.build b/ndctl/meson.build
index c7889af36084..050d5769c384 100644
--- a/ndctl/meson.build
+++ b/ndctl/meson.build
@@ -6,11 +6,9 @@ ndctl_src = [
   'check.c',
   'region.c',
   'dimm.c',
-  '../util/log.c',
   '../daxctl/filter.c',
   'filter.c',
   'list.c',
-  '../util/json.c',
   '../daxctl/json.c',
   'json.c',
   'json-smart.c',
diff --git a/util/meson.build b/util/meson.build
index 695037a924b9..a6ded7ee1473 100644
--- a/util/meson.build
+++ b/util/meson.build
@@ -3,6 +3,8 @@ util = static_library('util', [
   'parse-configs.c',
   'usage.c',
   'size.c',
+  'json.c',
+  'log.c',
   'main.c',
   'help.c',
   'strbuf.c',


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [ndctl PATCH 02/10] util: Use SZ_ size macros in display size
  2022-04-28 22:10 [ndctl PATCH 00/10] CXL topology unit test Dan Williams
  2022-04-28 22:10 ` [ndctl PATCH 01/10] build: Move utility helpers to libutil.a Dan Williams
@ 2022-04-28 22:10 ` Dan Williams
  2022-04-28 22:10 ` [ndctl PATCH 03/10] util: Pretty print terabytes Dan Williams
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Dan Williams @ 2022-04-28 22:10 UTC (permalink / raw)
  To: vishal.l.verma; +Cc: linux-cxl, nvdimm

In preparation for adding "Terabyte" support, cleanup the "1024"
multiplication with the SZ_* macros.

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 util/json.c |   11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/util/json.c b/util/json.c
index f8cc81f6e706..ebdf8d9eedd9 100644
--- a/util/json.c
+++ b/util/json.c
@@ -5,6 +5,7 @@
 #include <stdio.h>
 #include <util/util.h>
 #include <util/json.h>
+#include <util/size.h>
 #include <json-c/json.h>
 #include <json-c/printbuf.h>
 
@@ -27,24 +28,24 @@ static int display_size(struct json_object *jobj, struct printbuf *pbuf,
 	 * If prefix == JEDEC, we mean prefixes like kilo,mega,giga etc.
 	 */
 
-	if (bytes < 5000*1024)
+	if (bytes < 5000*SZ_1K)
 		snprintf(buf, sizeof(buf), "%lld", bytes);
 	else {
 		/* IEC */
-		if (bytes < 2*1024LL*1024LL*1024LL) {
-			long cMiB = (bytes * 200LL / (1LL<<20) +1) /2;
+		if (bytes < 2L*SZ_1G) {
+			long cMiB = (bytes * 200LL / SZ_1M+1) /2;
 
 			c = snprintf(buf, sizeof(buf), "\"%ld.%02ld MiB",
 					cMiB/100 , cMiB % 100);
 		} else {
-			long cGiB = (bytes * 200LL / (1LL<<30) +1) /2;
+			long cGiB = (bytes * 200LL / SZ_1G+1) /2;
 
 			c = snprintf(buf, sizeof(buf), "\"%ld.%02ld GiB",
 					cGiB/100 , cGiB % 100);
 		}
 
 		/* JEDEC */
-		if (bytes < 2*1024LL*1024LL*1024LL) {
+		if (bytes < 2L*SZ_1G) {
 			long cMB  = (bytes / (1000000LL / 200LL) + 1) / 2;
 
 			snprintf(buf + c, sizeof(buf) - c, " (%ld.%02ld MB)\"",


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [ndctl PATCH 03/10] util: Pretty print terabytes
  2022-04-28 22:10 [ndctl PATCH 00/10] CXL topology unit test Dan Williams
  2022-04-28 22:10 ` [ndctl PATCH 01/10] build: Move utility helpers to libutil.a Dan Williams
  2022-04-28 22:10 ` [ndctl PATCH 02/10] util: Use SZ_ size macros in display size Dan Williams
@ 2022-04-28 22:10 ` Dan Williams
  2022-04-28 22:10 ` [ndctl PATCH 04/10] cxl/port: Fix disable-port man page Dan Williams
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Dan Williams @ 2022-04-28 22:10 UTC (permalink / raw)
  To: vishal.l.verma; +Cc: linux-cxl, nvdimm

CXL capacities are such that gigabytes are too small of a unit for
displaying capacities. Add terabyte support to the display_size()
helper.

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 util/json.c |   15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/util/json.c b/util/json.c
index ebdf8d9eedd9..1d5c6bc7822e 100644
--- a/util/json.c
+++ b/util/json.c
@@ -37,11 +37,16 @@ static int display_size(struct json_object *jobj, struct printbuf *pbuf,
 
 			c = snprintf(buf, sizeof(buf), "\"%ld.%02ld MiB",
 					cMiB/100 , cMiB % 100);
-		} else {
+		} else if (bytes < 2*SZ_1T) {
 			long cGiB = (bytes * 200LL / SZ_1G+1) /2;
 
 			c = snprintf(buf, sizeof(buf), "\"%ld.%02ld GiB",
 					cGiB/100 , cGiB % 100);
+		} else {
+			long cTiB = (bytes * 200LL / SZ_1T+1) /2;
+
+			c = snprintf(buf, sizeof(buf), "\"%ld.%02ld TiB",
+					cTiB/100 , cTiB % 100);
 		}
 
 		/* JEDEC */
@@ -50,12 +55,18 @@ static int display_size(struct json_object *jobj, struct printbuf *pbuf,
 
 			snprintf(buf + c, sizeof(buf) - c, " (%ld.%02ld MB)\"",
 					cMB/100, cMB % 100);
-		} else {
+		} else if (bytes < 2*SZ_1T) {
 			long cGB  = (bytes / (1000000000LL/200LL) + 1) / 2;
 
 			snprintf(buf + c, sizeof(buf) - c, " (%ld.%02ld GB)\"",
 					cGB/100 , cGB % 100);
+		} else {
+			long cTB  = (bytes / (1000000000000LL/200LL) + 1) / 2;
+
+			snprintf(buf + c, sizeof(buf) - c, " (%ld.%02ld TB)\"",
+					cTB/100 , cTB % 100);
 		}
+
 	}
 
 	return printbuf_memappend(pbuf, buf, strlen(buf));


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [ndctl PATCH 04/10] cxl/port: Fix disable-port man page
  2022-04-28 22:10 [ndctl PATCH 00/10] CXL topology unit test Dan Williams
                   ` (2 preceding siblings ...)
  2022-04-28 22:10 ` [ndctl PATCH 03/10] util: Pretty print terabytes Dan Williams
@ 2022-04-28 22:10 ` Dan Williams
  2022-04-28 22:10 ` [ndctl PATCH 05/10] cxl/bus: Add bus disable support Dan Williams
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Dan Williams @ 2022-04-28 22:10 UTC (permalink / raw)
  To: vishal.l.verma; +Cc: linux-cxl, nvdimm

The man page was copied from the enable-port. Fix up some enable-port
leftovers, and duplicated --endpoint option description.

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 Documentation/cxl/cxl-disable-port.txt |    6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/Documentation/cxl/cxl-disable-port.txt b/Documentation/cxl/cxl-disable-port.txt
index de13c07d149b..ac56f20e8e6d 100644
--- a/Documentation/cxl/cxl-disable-port.txt
+++ b/Documentation/cxl/cxl-disable-port.txt
@@ -5,7 +5,7 @@ cxl-disable-port(1)
 
 NAME
 ----
-cxl-disable-port - activate / hot-add a given CXL port
+cxl-disable-port - disable / hot-remove a given CXL port and descendants
 
 SYNOPSIS
 --------
@@ -22,7 +22,6 @@ OPTIONS
 	Toggle from treating the port arguments as Switch Port identifiers to
 	Endpoint Port identifiers.
 
-
 -f::
 --force::
 	DANGEROUS: Override the safety measure that blocks attempts to disable a
@@ -31,9 +30,6 @@ OPTIONS
 	firmware and disabling an active device is akin to force removing memory
 	from a running system.
 
-	Toggle from treating the port arguments as Switch Port identifiers to
-	Endpoint Port identifiers.
-
 --debug::
 	If the cxl tool was built with debug disabled, turn on debug
 	messages.


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [ndctl PATCH 05/10] cxl/bus: Add bus disable support
  2022-04-28 22:10 [ndctl PATCH 00/10] CXL topology unit test Dan Williams
                   ` (3 preceding siblings ...)
  2022-04-28 22:10 ` [ndctl PATCH 04/10] cxl/port: Fix disable-port man page Dan Williams
@ 2022-04-28 22:10 ` Dan Williams
  2022-04-28 22:10 ` [ndctl PATCH 06/10] cxl/list: Auto-enable 'single' mode for port listings Dan Williams
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Dan Williams @ 2022-04-28 22:10 UTC (permalink / raw)
  To: vishal.l.verma; +Cc: linux-cxl, nvdimm

Route requests to disable the root back to unbinding the platform firmware
device, ACPI0017 for ACPI.CXL platforms.

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 Documentation/cxl/cxl-disable-bus.txt |   37 ++++++++
 Documentation/cxl/lib/libcxl.txt      |   12 ++
 Documentation/cxl/meson.build         |    1 
 cxl/builtin.h                         |    1 
 cxl/bus.c                             |  159 +++++++++++++++++++++++++++++++++
 cxl/cxl.c                             |    1 
 cxl/filter.c                          |    3 -
 cxl/filter.h                          |    1 
 cxl/lib/libcxl.c                      |   15 +++
 cxl/lib/libcxl.sym                    |    1 
 cxl/libcxl.h                          |    1 
 cxl/meson.build                       |    1 
 12 files changed, 231 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/cxl/cxl-disable-bus.txt
 create mode 100644 cxl/bus.c

diff --git a/Documentation/cxl/cxl-disable-bus.txt b/Documentation/cxl/cxl-disable-bus.txt
new file mode 100644
index 000000000000..65f695cd06c8
--- /dev/null
+++ b/Documentation/cxl/cxl-disable-bus.txt
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: GPL-2.0
+
+cxl-disable-bus(1)
+===================
+
+NAME
+----
+cxl-disable-bus - Shutdown an entire tree of CXL devices
+
+SYNOPSIS
+--------
+[verse]
+'cxl disable-bus' <root0> [<root1>..<rootN>] [<options>]
+
+For test and debug scenarios, disable a CXL bus and any associated
+memory devices from CXL.mem operations.
+
+OPTIONS
+-------
+-f::
+--force::
+	DANGEROUS: Override the safety measure that blocks attempts to disable a
+	bus if the tool determines a descendent memdev is in active usage.
+	Recall that CXL memory ranges might have been established by platform
+	firmware and disabling an active device is akin to force removing memory
+	from a running system.
+
+--debug::
+	If the cxl tool was built with debug disabled, turn on debug
+	messages.
+
+
+include::../copyright.txt[]
+
+SEE ALSO
+--------
+linkcxl:cxl-disable-port[1]
diff --git a/Documentation/cxl/lib/libcxl.txt b/Documentation/cxl/lib/libcxl.txt
index 7b223cbcac3f..f8f0e668ab59 100644
--- a/Documentation/cxl/lib/libcxl.txt
+++ b/Documentation/cxl/lib/libcxl.txt
@@ -216,6 +216,18 @@ discovery order. The possible provider names are 'ACPI.CXL' and
 the kernel device names that are subject to change based on discovery
 order.
 
+=== BUS: Control
+----
+int cxl_bus_disable_invalidate(struct cxl_bus *bus);
+----
+
+An entire CXL topology can be torn down with this API. Like other
+_invalidate APIs callers must assume that all library objects have been
+freed. This one goes one step further and also frees the @bus argument.
+This may crash the system and is only useful in kernel driver
+development scenarios.
+
+
 PORTS
 -----
 CXL ports track the PCIe hierarchy between a platform firmware CXL root
diff --git a/Documentation/cxl/meson.build b/Documentation/cxl/meson.build
index e927644a3826..974a5a41d169 100644
--- a/Documentation/cxl/meson.build
+++ b/Documentation/cxl/meson.build
@@ -34,6 +34,7 @@ cxl_manpages = [
   'cxl-disable-memdev.txt',
   'cxl-enable-port.txt',
   'cxl-disable-port.txt',
+  'cxl-disable-bus.txt',
   'cxl-set-partition.txt',
 ]
 
diff --git a/cxl/builtin.h b/cxl/builtin.h
index 7bbad98f67ac..a437bc314a30 100644
--- a/cxl/builtin.h
+++ b/cxl/builtin.h
@@ -15,4 +15,5 @@ int cmd_enable_memdev(int argc, const char **argv, struct cxl_ctx *ctx);
 int cmd_disable_port(int argc, const char **argv, struct cxl_ctx *ctx);
 int cmd_enable_port(int argc, const char **argv, struct cxl_ctx *ctx);
 int cmd_set_partition(int argc, const char **argv, struct cxl_ctx *ctx);
+int cmd_disable_bus(int argc, const char **argv, struct cxl_ctx *ctx);
 #endif /* _CXL_BUILTIN_H_ */
diff --git a/cxl/bus.c b/cxl/bus.c
new file mode 100644
index 000000000000..33212951a404
--- /dev/null
+++ b/cxl/bus.c
@@ -0,0 +1,159 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (C) 2020-2022 Intel Corporation. All rights reserved. */
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <limits.h>
+#include <util/log.h>
+#include <cxl/libcxl.h>
+#include <util/parse-options.h>
+#include <ccan/minmax/minmax.h>
+#include <ccan/array_size/array_size.h>
+
+#include "filter.h"
+
+static struct parameters {
+	bool debug;
+	bool force;
+} param;
+
+static struct log_ctx bl;
+
+#define BASE_OPTIONS()                                                 \
+OPT_BOOLEAN(0, "debug", &param.debug, "turn on debug")
+
+#define DISABLE_OPTIONS()                                              \
+OPT_BOOLEAN('f', "force", &param.force,                                \
+	    "DANGEROUS: override active memdev safety checks")
+
+static const struct option disable_options[] = {
+	BASE_OPTIONS(),
+	DISABLE_OPTIONS(),
+	OPT_END(),
+};
+
+static int action_disable(struct cxl_bus *bus)
+{
+	const char *devname = cxl_bus_get_devname(bus);
+	struct cxl_ctx *ctx = cxl_bus_get_ctx(bus);
+	struct cxl_memdev *memdev;
+	int active_memdevs = 0;
+
+	cxl_memdev_foreach(ctx, memdev)
+		if (bus == cxl_memdev_get_bus(memdev))
+			active_memdevs++;
+
+	if (active_memdevs && !param.force) {
+		/*
+		 * TODO: actually detect rather than assume active just
+		 * because the memdev is enabled
+		 */
+		log_err(&bl,
+			"%s hosts %d memdev%s which %s part of an active region\n",
+			devname, active_memdevs, active_memdevs > 1 ? "s" : "",
+			active_memdevs > 1 ? "are" : "is");
+		log_err(&bl,
+			"See 'cxl list -M -b %s' to see impacted device%s\n",
+			devname, active_memdevs > 1 ? "s" : "");
+		return -EBUSY;
+	}
+
+	return cxl_bus_disable_invalidate(bus);
+}
+
+static struct cxl_bus *find_cxl_bus(struct cxl_ctx *ctx, const char *ident)
+{
+	struct cxl_bus *bus;
+
+	cxl_bus_foreach(ctx, bus)
+		if (util_cxl_bus_filter(bus, ident))
+			return bus;
+	return NULL;
+}
+
+static int bus_action(int argc, const char **argv, struct cxl_ctx *ctx,
+		      int (*action)(struct cxl_bus *bus),
+		      const struct option *options, const char *usage)
+{
+	int i, rc = 0, count = 0, err = 0;
+	const char * const u[] = {
+		usage,
+		NULL
+	};
+	unsigned long id;
+
+	log_init(&bl, "cxl bus", "CXL_PORT_LOG");
+	argc = parse_options(argc, argv, options, u, 0);
+
+	if (argc == 0)
+		usage_with_options(u, options);
+	for (i = 0; i < argc; i++) {
+		if (strcmp(argv[i], "all") == 0) {
+			argv[0] = "all";
+			argc = 1;
+			break;
+		}
+
+		if (sscanf(argv[i], "root%lu", &id) == 1)
+			continue;
+		if (sscanf(argv[i], "%lu", &id) == 1)
+			continue;
+
+		log_err(&bl, "'%s' is not a valid bus identifer\n", argv[i]);
+		err++;
+	}
+
+	if (err == argc) {
+		usage_with_options(u, options);
+		return -EINVAL;
+	}
+
+	if (param.debug) {
+		cxl_set_log_priority(ctx, LOG_DEBUG);
+		bl.log_priority = LOG_DEBUG;
+	} else
+		bl.log_priority = LOG_INFO;
+
+	rc = 0;
+	err = 0;
+	count = 0;
+
+	for (i = 0; i < argc; i++) {
+		struct cxl_bus *bus;
+
+		bus = find_cxl_bus(ctx, argv[i]);
+		if (!bus) {
+			log_dbg(&bl, "bus: %s not found\n", argv[i]);
+			continue;
+		}
+
+		log_dbg(&bl, "run action on bus: %s\n",
+			cxl_bus_get_devname(bus));
+		rc = action(bus);
+		if (rc == 0)
+			count++;
+		else if (rc && !err)
+			err = rc;
+	}
+	rc = err;
+
+	/*
+	 * count if some actions succeeded, 0 if none were attempted,
+	 * negative error code otherwise.
+	 */
+	if (count > 0)
+		return count;
+	return rc;
+}
+
+ int cmd_disable_bus(int argc, const char **argv, struct cxl_ctx *ctx)
+ {
+	 int count = bus_action(
+		 argc, argv, ctx, action_disable, disable_options,
+		 "cxl disable-bus <bus0> [<bus1>..<busN>] [<options>]");
+
+	 log_info(&bl, "disabled %d bus%s\n", count >= 0 ? count : 0,
+		  count > 1 ? "s" : "");
+	 return count >= 0 ? 0 : EXIT_FAILURE;
+ }
diff --git a/cxl/cxl.c b/cxl/cxl.c
index ab4bbeccaa76..aa4ce61b7c87 100644
--- a/cxl/cxl.c
+++ b/cxl/cxl.c
@@ -69,6 +69,7 @@ static struct cmd_struct commands[] = {
 	{ "disable-port", .c_fn = cmd_disable_port },
 	{ "enable-port", .c_fn = cmd_enable_port },
 	{ "set-partition", .c_fn = cmd_set_partition },
+	{ "disable-bus", .c_fn = cmd_disable_bus },
 };
 
 int main(int argc, const char **argv)
diff --git a/cxl/filter.c b/cxl/filter.c
index b3396426dda8..c6ab9eb58124 100644
--- a/cxl/filter.c
+++ b/cxl/filter.c
@@ -176,8 +176,7 @@ util_cxl_decoder_filter_by_port(struct cxl_decoder *decoder, const char *ident,
 	return NULL;
 }
 
-static struct cxl_bus *util_cxl_bus_filter(struct cxl_bus *bus,
-					   const char *__ident)
+struct cxl_bus *util_cxl_bus_filter(struct cxl_bus *bus, const char *__ident)
 {
 	char *ident, *save;
 	const char *arg;
diff --git a/cxl/filter.h b/cxl/filter.h
index 697b7779c08e..955794366d5c 100644
--- a/cxl/filter.h
+++ b/cxl/filter.h
@@ -41,6 +41,7 @@ enum cxl_port_filter_mode {
 
 struct cxl_port *util_cxl_port_filter(struct cxl_port *port, const char *ident,
 				      enum cxl_port_filter_mode mode);
+struct cxl_bus *util_cxl_bus_filter(struct cxl_bus *bus, const char *__ident);
 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,
diff --git a/cxl/lib/libcxl.c b/cxl/lib/libcxl.c
index 59e164464987..0e8dd20e3c47 100644
--- a/cxl/lib/libcxl.c
+++ b/cxl/lib/libcxl.c
@@ -556,6 +556,21 @@ static void bus_invalidate(struct cxl_bus *bus)
 	cxl_flush(ctx);
 }
 
+CXL_EXPORT int cxl_bus_disable_invalidate(struct cxl_bus *bus)
+{
+	struct cxl_ctx *ctx = cxl_bus_get_ctx(bus);
+	struct cxl_port *port = cxl_bus_get_port(bus);
+	int rc;
+
+	rc = util_unbind(port->uport, ctx);
+	if (rc)
+		return rc;
+
+	free_bus(bus, &ctx->buses);
+	cxl_flush(ctx);
+	return 0;
+}
+
 CXL_EXPORT int cxl_memdev_disable_invalidate(struct cxl_memdev *memdev)
 {
 	struct cxl_ctx *ctx = cxl_memdev_get_ctx(memdev);
diff --git a/cxl/lib/libcxl.sym b/cxl/lib/libcxl.sym
index aab1112a91d8..dffcb60b8dd0 100644
--- a/cxl/lib/libcxl.sym
+++ b/cxl/lib/libcxl.sym
@@ -86,6 +86,7 @@ global:
 	cxl_bus_get_id;
 	cxl_bus_get_port;
 	cxl_bus_get_ctx;
+	cxl_bus_disable_invalidate;
 	cxl_port_get_first;
 	cxl_port_get_next;
 	cxl_port_get_devname;
diff --git a/cxl/libcxl.h b/cxl/libcxl.h
index 0063d31ab398..0007f4d9bcee 100644
--- a/cxl/libcxl.h
+++ b/cxl/libcxl.h
@@ -73,6 +73,7 @@ const char *cxl_bus_get_devname(struct cxl_bus *bus);
 int cxl_bus_get_id(struct cxl_bus *bus);
 struct cxl_port *cxl_bus_get_port(struct cxl_bus *bus);
 struct cxl_ctx *cxl_bus_get_ctx(struct cxl_bus *bus);
+int cxl_bus_disable_invalidate(struct cxl_bus *bus);
 
 #define cxl_bus_foreach(ctx, bus)                                              \
 	for (bus = cxl_bus_get_first(ctx); bus != NULL;                        \
diff --git a/cxl/meson.build b/cxl/meson.build
index 671c8e1626ef..d63dcb12eec2 100644
--- a/cxl/meson.build
+++ b/cxl/meson.build
@@ -2,6 +2,7 @@ cxl_src = [
   'cxl.c',
   'list.c',
   'port.c',
+  'bus.c',
   'memdev.c',
   'json.c',
   'filter.c',


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [ndctl PATCH 06/10] cxl/list: Auto-enable 'single' mode for port listings
  2022-04-28 22:10 [ndctl PATCH 00/10] CXL topology unit test Dan Williams
                   ` (4 preceding siblings ...)
  2022-04-28 22:10 ` [ndctl PATCH 05/10] cxl/bus: Add bus disable support Dan Williams
@ 2022-04-28 22:10 ` Dan Williams
  2022-04-28 22:10 ` [ndctl PATCH 07/10] cxl/memdev: Fix bus_invalidate() crash Dan Williams
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Dan Williams @ 2022-04-28 22:10 UTC (permalink / raw)
  To: vishal.l.verma; +Cc: linux-cxl, nvdimm

The --single parameter instructs the filter code to gate listing of
ancestor ports. However, that behavior can be inferred by attempts to list
a port without the --ports option, i.e. make:

    cxl list -p $port

...equivalent to:

    cxl list -P -S -p $port

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 cxl/list.c |    1 +
 1 file changed, 1 insertion(+)

diff --git a/cxl/list.c b/cxl/list.c
index 1e9d441190a0..940782d33a10 100644
--- a/cxl/list.c
+++ b/cxl/list.c
@@ -104,6 +104,7 @@ int cmd_list(int argc, const char **argv, struct cxl_ctx *ctx)
 			error("please specify entities to list, e.g. using -m/-M\n");
 			usage_with_options(u, options);
 		}
+		param.single = true;
 	}
 
 	log_init(&param.ctx, "cxl list", "CXL_LIST_LOG");


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [ndctl PATCH 07/10] cxl/memdev: Fix bus_invalidate() crash
  2022-04-28 22:10 [ndctl PATCH 00/10] CXL topology unit test Dan Williams
                   ` (5 preceding siblings ...)
  2022-04-28 22:10 ` [ndctl PATCH 06/10] cxl/list: Auto-enable 'single' mode for port listings Dan Williams
@ 2022-04-28 22:10 ` Dan Williams
  2022-04-28 22:10 ` [ndctl PATCH 08/10] cxl/list: Add support for filtering by host identifiers Dan Williams
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Dan Williams @ 2022-04-28 22:10 UTC (permalink / raw)
  To: vishal.l.verma; +Cc: linux-cxl, nvdimm

bus_invalidate() attempts to limit the invalidation of memdevs to a single
bus scope. However, the ordering of bus_invalidate() leads to a use after
free. Unconditionally invalidate memdevs (disconnect memdevs from their
endpoints) and resotre on next lookup. Otherwise the following command
results in the following backtrace with cxl_test:

    cxl disable-memdev 5,1 --force

#2  0x00007ffff7fb97d4 in snprintf (__fmt=0x7ffff7fbc3ed "%s/driver", __n=98,
    __s=0x574d545619f7bae2 <error: Cannot access memory at address 0x574d545619f7bae2>)
    at /usr/include/bits/stdio2.h:71
#3  cxl_port_is_enabled (port=port@entry=0x422eb0) at ../cxl/lib/libcxl.c:1379
#4  0x00007ffff7fb99a9 in cxl_port_get_bus (port=0x422eb0) at ../cxl/lib/libcxl.c:1339
#5  0x00007ffff7fba3d0 in bus_invalidate (bus=bus@entry=0x421740) at ../cxl/lib/libcxl.c:549
#6  0x00007ffff7fba4e7 in cxl_memdev_disable_invalidate (memdev=0x416fd0) at ../cxl/lib/libcxl.c:596
#7  0x000000000040624e in memdev_action (argc=<optimized out>, argv=<optimized out>, ctx=0x4152a0,
    action=action@entry=0x406b70 <action_disable>, options=options@entry=0x40fca0 <disable_options>,
    usage=usage@entry=0x40f4b0 "cxl disable-memdev <mem0> [<mem1>..<memN>] [<options>]")
    at ../cxl/memdev.c:506
#8  0x0000000000406d57 in cmd_disable_memdev (argc=<optimized out>, argv=<optimized out>,

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 cxl/lib/libcxl.c |    3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/cxl/lib/libcxl.c b/cxl/lib/libcxl.c
index 0e8dd20e3c47..374b0f13905a 100644
--- a/cxl/lib/libcxl.c
+++ b/cxl/lib/libcxl.c
@@ -546,8 +546,7 @@ static void bus_invalidate(struct cxl_bus *bus)
 	 * indeterminate, delete them all and start over.
 	 */
 	cxl_memdev_foreach(ctx, memdev)
-		if (cxl_memdev_get_bus(memdev) == bus)
-			memdev->endpoint = NULL;
+		memdev->endpoint = NULL;
 
 	bus_port = cxl_bus_get_port(bus);
 	list_for_each_safe(&bus_port->child_ports, port, _p, list)


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [ndctl PATCH 08/10] cxl/list: Add support for filtering by host identifiers
  2022-04-28 22:10 [ndctl PATCH 00/10] CXL topology unit test Dan Williams
                   ` (6 preceding siblings ...)
  2022-04-28 22:10 ` [ndctl PATCH 07/10] cxl/memdev: Fix bus_invalidate() crash Dan Williams
@ 2022-04-28 22:10 ` Dan Williams
  2022-04-28 22:10 ` [ndctl PATCH 09/10] cxl/port: Relax port identifier validation Dan Williams
  2022-04-28 22:10 ` [ndctl PATCH 10/10] cxl/test: Add topology enumeration and hotplug test Dan Williams
  9 siblings, 0 replies; 11+ messages in thread
From: Dan Williams @ 2022-04-28 22:10 UTC (permalink / raw)
  To: vishal.l.verma; +Cc: linux-cxl, nvdimm

Accept host device names as valid filters for memdevs, ports, and
endpoints.

# cxl list -u -m 7
{
  "memdev":"mem7",
  "pmem_size":"256.00 MiB (268.44 MB)",
  "ram_size":"256.00 MiB (268.44 MB)",
  "serial":"0x6",
  "numa_node":0,
  "host":"cxl_mem.6"
}

# cxl list -u -m cxl_mem.6
{
  "memdev":"mem7",
  "pmem_size":"256.00 MiB (268.44 MB)",
  "ram_size":"256.00 MiB (268.44 MB)",
  "serial":"0x6",
  "numa_node":0,
  "host":"cxl_mem.6"
}

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 cxl/filter.c |    9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/cxl/filter.c b/cxl/filter.c
index c6ab9eb58124..66fd7420144a 100644
--- a/cxl/filter.c
+++ b/cxl/filter.c
@@ -73,6 +73,9 @@ struct cxl_endpoint *util_cxl_endpoint_filter(struct cxl_endpoint *endpoint,
 
 		if (strcmp(arg, cxl_endpoint_get_devname(endpoint)) == 0)
 			break;
+
+		if (strcmp(arg, cxl_endpoint_get_host(endpoint)) == 0)
+			break;
 	}
 
 	free(ident);
@@ -116,6 +119,9 @@ static struct cxl_port *__util_cxl_port_filter(struct cxl_port *port,
 
 		if (strcmp(arg, cxl_port_get_devname(port)) == 0)
 			break;
+
+		if (strcmp(arg, cxl_port_get_host(port)) == 0)
+			break;
 	}
 
 	free(ident);
@@ -303,6 +309,9 @@ struct cxl_memdev *util_cxl_memdev_filter(struct cxl_memdev *memdev,
 
 		if (strcmp(name, cxl_memdev_get_devname(memdev)) == 0)
 			break;
+
+		if (strcmp(name, cxl_memdev_get_host(memdev)) == 0)
+			break;
 	}
 
 	free(ident);


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [ndctl PATCH 09/10] cxl/port: Relax port identifier validation
  2022-04-28 22:10 [ndctl PATCH 00/10] CXL topology unit test Dan Williams
                   ` (7 preceding siblings ...)
  2022-04-28 22:10 ` [ndctl PATCH 08/10] cxl/list: Add support for filtering by host identifiers Dan Williams
@ 2022-04-28 22:10 ` Dan Williams
  2022-04-28 22:10 ` [ndctl PATCH 10/10] cxl/test: Add topology enumeration and hotplug test Dan Williams
  9 siblings, 0 replies; 11+ messages in thread
From: Dan Williams @ 2022-04-28 22:10 UTC (permalink / raw)
  To: vishal.l.verma; +Cc: linux-cxl, nvdimm

Now that util_cxl_port_filter() accepts port host identifiers it is no
longer possible to pre-validate that the port arguments follow the "port%d"
format. Instead, let all inputs through and warn if the filter fails to
identify a port.

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 cxl/port.c |   30 ++++--------------------------
 1 file changed, 4 insertions(+), 26 deletions(-)

diff --git a/cxl/port.c b/cxl/port.c
index 46a8f32df8e1..89f3916d85aa 100644
--- a/cxl/port.c
+++ b/cxl/port.c
@@ -145,7 +145,6 @@ static int port_action(int argc, const char **argv, struct cxl_ctx *ctx,
 		usage,
 		NULL
 	};
-	unsigned long id;
 
 	log_init(&pl, "cxl port", "CXL_PORT_LOG");
 	argc = parse_options(argc, argv, options, u, 0);
@@ -153,31 +152,10 @@ static int port_action(int argc, const char **argv, struct cxl_ctx *ctx,
 	if (argc == 0)
 		usage_with_options(u, options);
 	for (i = 0; i < argc; i++) {
-		const char *fmt;
-
 		if (strcmp(argv[i], "all") == 0) {
 			argc = 1;
 			break;
 		}
-
-		if (param.endpoint)
-			fmt = "endpoint%lu";
-		else
-			fmt = "port%lu";
-
-		if (sscanf(argv[i], fmt, &id) == 1)
-			continue;
-		if (sscanf(argv[i], "%lu", &id) == 1)
-			continue;
-
-		log_err(&pl, "'%s' is not a valid %s identifer\n", argv[i],
-			param.endpoint ? "endpoint" : "port");
-		err++;
-	}
-
-	if (err == argc) {
-		usage_with_options(u, options);
-		return -EINVAL;
 	}
 
 	if (param.debug) {
@@ -187,7 +165,6 @@ static int port_action(int argc, const char **argv, struct cxl_ctx *ctx,
 		pl.log_priority = LOG_INFO;
 
 	rc = 0;
-	err = 0;
 	count = 0;
 
 	for (i = 0; i < argc; i++) {
@@ -198,15 +175,16 @@ static int port_action(int argc, const char **argv, struct cxl_ctx *ctx,
 
 			endpoint = find_cxl_endpoint(ctx, argv[i]);
 			if (!endpoint) {
-				log_dbg(&pl, "endpoint: %s not found\n",
-					argv[i]);
+				log_notice(&pl, "endpoint: %s not found\n",
+					   argv[i]);
 				continue;
 			}
 			port = cxl_endpoint_get_port(endpoint);
 		} else {
 			port = find_cxl_port(ctx, argv[i]);
 			if (!port) {
-				log_dbg(&pl, "port: %s not found\n", argv[i]);
+				log_notice(&pl, "port: %s not found\n",
+					   argv[i]);
 				continue;
 			}
 		}


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [ndctl PATCH 10/10] cxl/test: Add topology enumeration and hotplug test
  2022-04-28 22:10 [ndctl PATCH 00/10] CXL topology unit test Dan Williams
                   ` (8 preceding siblings ...)
  2022-04-28 22:10 ` [ndctl PATCH 09/10] cxl/port: Relax port identifier validation Dan Williams
@ 2022-04-28 22:10 ` Dan Williams
  9 siblings, 0 replies; 11+ messages in thread
From: Dan Williams @ 2022-04-28 22:10 UTC (permalink / raw)
  To: vishal.l.verma; +Cc: Luis Chamberlain, linux-cxl, nvdimm

Test the re-plug of memdevs, switch ports, root ports, and bus objects.

Cc: Luis Chamberlain <mcgrof@kernel.org>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 test/common          |   12 ++++
 test/cxl-topology.sh |  166 ++++++++++++++++++++++++++++++++++++++++++++++++++
 test/meson.build     |    2 +
 3 files changed, 180 insertions(+)
 create mode 100644 test/cxl-topology.sh

diff --git a/test/common b/test/common
index fb487958a29b..65615cc09a3e 100644
--- a/test/common
+++ b/test/common
@@ -27,6 +27,18 @@ if [ -z $DAXCTL ]; then
 	fi
 fi
 
+# CXL
+if [ -z $CXL ]; then
+	if [ -f "../cxl/cxl" ] && [ -x "../cxl/cxl" ]; then
+		export CXL=../cxl/cxl
+	elif [ -f "./cxl/cxl" ] && [ -x "./cxl/cxl" ]; then
+		export CXL=./cxl/cxl
+	else
+		echo "Couldn't find a cxl binary"
+		exit 1
+	fi
+fi
+
 if [ -z $TEST_PATH ]; then
 	export TEST_PATH=.
 fi
diff --git a/test/cxl-topology.sh b/test/cxl-topology.sh
new file mode 100644
index 000000000000..ff11614f4f14
--- /dev/null
+++ b/test/cxl-topology.sh
@@ -0,0 +1,166 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (C) 2022 Intel Corporation. All rights reserved.
+
+. $(dirname $0)/common
+
+rc=1
+
+set -ex
+
+trap 'err $LINENO' ERR
+
+check_prereq "jq"
+
+modprobe -r cxl_test
+modprobe cxl_test
+udevadm settle
+
+# THEORY OF OPERATION: Validate the hard coded assumptions of the
+# cxl_test.ko module that defines its topology in
+# tools/testing/cxl/test/cxl.c. If that model ever changes then the
+# paired update must be made to this test.
+
+# collect cxl_test root device id
+json=$($CXL list -b cxl_test)
+count=$(jq "length" <<< $json)
+((count == 1)) || err "$LINENO"
+root=$(jq -r ".[] | .bus" <<< $json)
+
+
+# validate 2 host bridges under a root port
+port_sort="sort_by(.port | .[4:] | tonumber)"
+json=$($CXL list -b cxl_test -BP)
+count=$(jq ".[] | .[\"ports:$root\"] | length" <<< $json)
+((count == 2)) || err "$LINENO"
+
+bridge[0]=$(jq -r ".[] | .[\"ports:$root\"] | $port_sort | .[0].port" <<< $json)
+bridge[1]=$(jq -r ".[] | .[\"ports:$root\"] | $port_sort | .[1].port" <<< $json)
+
+
+# validate 2 root ports per host bridge
+json=$($CXL list -b cxl_test -T -p ${bridge[0]})
+count=$(jq ".[] | .dports | length" <<< $json)
+((count == 2)) || err "$LINENO"
+
+json=$($CXL list -b cxl_test -T -p ${bridge[1]})
+count=$(jq ".[] | .dports | length" <<< $json)
+((count == 2)) || err "$LINENO"
+
+
+# validate 2 switches per-root port
+json=$($CXL list -b cxl_test -P -p ${bridge[0]})
+count=$(jq ".[] | .[\"ports:${bridge[0]}\"] | length" <<< $json)
+((count == 2)) || err "$LINENO"
+
+switch[0]=$(jq -r ".[] | .[\"ports:${bridge[0]}\"] | $port_sort | .[0].host" <<< $json)
+switch[1]=$(jq -r ".[] | .[\"ports:${bridge[0]}\"] | $port_sort | .[1].host" <<< $json)
+
+json=$($CXL list -b cxl_test -P -p ${bridge[1]})
+count=$(jq ".[] | .[\"ports:${bridge[1]}\"] | length" <<< $json)
+((count == 2)) || err "$LINENO"
+
+switch[2]=$(jq -r ".[] | .[\"ports:${bridge[1]}\"] | $port_sort | .[0].host" <<< $json)
+switch[3]=$(jq -r ".[] | .[\"ports:${bridge[1]}\"] | $port_sort | .[1].host" <<< $json)
+
+
+# check that all 8 cxl_test memdevs are enabled by default and have a
+# pmem size of 256M
+json=$($CXL list -b cxl_test -M)
+count=$(jq "map(select(.pmem_size == $((256 << 20)))) | length" <<< $json)
+((count == 8)) || err "$LINENO"
+
+
+# validate the expected properties of the 4 root decoders
+json=$($CXL list -b cxl_test -D -d root)
+port_id=${root:4}
+port_id_len=${#port_id}
+decoder_sort="sort_by(.decoder | .[$((8+port_id_len)):] | tonumber)"
+count=$(jq "[ $decoder_sort | .[0] |
+	select(.volatile_capable == true) |
+	select(.size == $((256 << 20))) |
+	select(.nr_targets == 1) ] | length" <<< $json)
+((count == 1)) || err "$LINENO"
+
+count=$(jq "[ $decoder_sort | .[1] |
+	select(.volatile_capable == true) |
+	select(.size == $((512 << 20))) |
+	select(.nr_targets == 2) ] | length" <<< $json)
+((count == 1)) || err "$LINENO"
+
+count=$(jq "[ $decoder_sort | .[2] |
+	select(.pmem_capable == true) |
+	select(.size == $((256 << 20))) |
+	select(.nr_targets == 1) ] | length" <<< $json)
+((count == 1)) || err "$LINENO"
+
+count=$(jq "[ $decoder_sort | .[3] |
+	select(.pmem_capable == true) |
+	select(.size == $((512 << 20))) |
+	select(.nr_targets == 2) ] | length" <<< $json)
+((count == 1)) || err "$LINENO"
+
+# check that switch ports disappear after all of their memdevs have been
+# disabled, and return when the memdevs are enabled.
+for s in ${switch[@]}
+do
+	json=$($CXL list -M -p $s)
+	count=$(jq "length" <<< $json)
+	((count == 2)) || err "$LINENO"
+
+	mem[0]=$(jq -r ".[0] | .memdev" <<< $json)
+	mem[1]=$(jq -r ".[1] | .memdev" <<< $json)
+
+	$CXL disable-memdev ${mem[0]} --force
+	json=$($CXL list -p $s)
+	count=$(jq "length" <<< $json)
+	((count == 1)) || err "$LINENO"
+
+	$CXL disable-memdev ${mem[1]} --force
+	json=$($CXL list -p $s)
+	count=$(jq "length" <<< $json)
+	((count == 0)) || err "$LINENO"
+
+	$CXL enable-memdev ${mem[0]}
+	$CXL enable-memdev ${mem[1]}
+
+	json=$($CXL list -p $s)
+	count=$(jq "length" <<< $json)
+	((count == 1)) || err "$LINENO"
+
+	$CXL disable-port $s --force
+	json=$($CXL list -p $s)
+	count=$(jq "length" <<< $json)
+	((count == 0)) || err "$LINENO"
+
+	$CXL enable-memdev ${mem[0]} ${mem[1]}
+	json=$($CXL list -p $s)
+	count=$(jq "length" <<< $json)
+	((count == 1)) || err "$LINENO"
+done
+
+
+# validate host bridge tear down
+for b in ${bridge[@]}
+do
+	$CXL disable-port $b -f
+	json=$($CXL list -M -i -p $b)
+	count=$(jq "map(select(.state == \"disabled\")) | length" <<< $json)
+	((count == 4)) || err "$LINENO"
+
+	$CXL enable-port $b -m
+	json=$($CXL list -M -p $b)
+	count=$(jq "length" <<< $json)
+	((count == 4)) || err "$LINENO"
+done
+
+
+# validate that the bus can be disabled without issue
+$CXL disable-bus $root -f
+
+
+# validate no WARN or lockdep report during the run
+log=$(journalctl -r -k --since "-$((SECONDS+1))s")
+grep -q "Call Trace" <<< $log && err "$LINENO"
+
+modprobe -r cxl_test
diff --git a/test/meson.build b/test/meson.build
index 7ccd45195236..210dcb0b5ff1 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -150,6 +150,7 @@ monitor = find_program('monitor.sh')
 max_extent = find_program('max_available_extent_ns.sh')
 pfn_meta_errors = find_program('pfn-meta-errors.sh')
 track_uuid = find_program('track-uuid.sh')
+cxl_topo = find_program('cxl-topology.sh')
 
 tests = [
   [ 'libndctl',               libndctl,		  'ndctl' ],
@@ -174,6 +175,7 @@ tests = [
   [ 'max_extent_ns',          max_extent,	  'ndctl' ],
   [ 'pfn-meta-errors.sh',     pfn_meta_errors,	  'ndctl' ],
   [ 'track-uuid.sh',          track_uuid,	  'ndctl' ],
+  [ 'cxl-topology.sh',	      cxl_topo,		  'cxl'   ],
 ]
 
 if get_option('destructive').enabled()


^ permalink raw reply related	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2022-04-28 22:10 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-04-28 22:10 [ndctl PATCH 00/10] CXL topology unit test Dan Williams
2022-04-28 22:10 ` [ndctl PATCH 01/10] build: Move utility helpers to libutil.a Dan Williams
2022-04-28 22:10 ` [ndctl PATCH 02/10] util: Use SZ_ size macros in display size Dan Williams
2022-04-28 22:10 ` [ndctl PATCH 03/10] util: Pretty print terabytes Dan Williams
2022-04-28 22:10 ` [ndctl PATCH 04/10] cxl/port: Fix disable-port man page Dan Williams
2022-04-28 22:10 ` [ndctl PATCH 05/10] cxl/bus: Add bus disable support Dan Williams
2022-04-28 22:10 ` [ndctl PATCH 06/10] cxl/list: Auto-enable 'single' mode for port listings Dan Williams
2022-04-28 22:10 ` [ndctl PATCH 07/10] cxl/memdev: Fix bus_invalidate() crash Dan Williams
2022-04-28 22:10 ` [ndctl PATCH 08/10] cxl/list: Add support for filtering by host identifiers Dan Williams
2022-04-28 22:10 ` [ndctl PATCH 09/10] cxl/port: Relax port identifier validation Dan Williams
2022-04-28 22:10 ` [ndctl PATCH 10/10] cxl/test: Add topology enumeration and hotplug test Dan Williams

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.