On Thu, Dec 9, 2021 at 12:23 PM Vishal Verma <[email protected]> wrote:
>
> CXL - or Compute eXpress Link - is a new interconnect that extends PCIe
> to support a wide range of devices, including cache coherent memory
> expanders. As such, these devices can be new sources of 'persistent
> memory', and the 'ndctl' umbrella of tools and libraries needs to be able
> to interact with them.
>
> Add a new utility and library for managing these CXL memory devices. This
> is an initial bring-up for interacting with CXL devices, and only includes
> adding the utility and library infrastructure, parsing device information
> from sysfs for CXL devices, and providing a 'cxl-list' command to
> display this information in JSON formatted output.
>
> Cc: Ben Widawsky <[email protected]>
> Cc: Dan Williams <[email protected]>
> Reviewed-by: Dan Williams <[email protected]>
> Signed-off-by: Vishal Verma <[email protected]>
> ---
>
> Changes in v6:
> - Remove the cxl-list default of listing memdevs as we may want to list
> regions by default, once that support is available. For now just error
> out if memdevs are not explicitly asked for. (Dan)
>
> Documentation/cxl/cxl-list.txt | 64 +++++
> Documentation/cxl/cxl.txt | 34 +++
> Documentation/cxl/human-option.txt | 8 +
> Documentation/cxl/verbose-option.txt | 5 +
> configure.ac | 3 +
> Makefile.am | 8 +-
> Makefile.am.in | 4 +
> cxl/lib/private.h | 29 +++
> cxl/lib/libcxl.c | 345 +++++++++++++++++++++++++++
> cxl/builtin.h | 8 +
> cxl/libcxl.h | 55 +++++
> util/filter.h | 2 +
> util/json.h | 3 +
> util/main.h | 3 +
> cxl/cxl.c | 96 ++++++++
> cxl/list.c | 121 ++++++++++
> util/filter.c | 20 ++
> util/json.c | 26 ++
> .clang-format | 1 +
> .gitignore | 4 +-
> Documentation/cxl/Makefile.am | 58 +++++
> cxl/Makefile.am | 21 ++
> cxl/lib/Makefile.am | 32 +++
> cxl/lib/libcxl.pc.in | 11 +
> cxl/lib/libcxl.sym | 25 ++
> 25 files changed, 982 insertions(+), 4 deletions(-)
> create mode 100644 Documentation/cxl/cxl-list.txt
> create mode 100644 Documentation/cxl/cxl.txt
> create mode 100644 Documentation/cxl/human-option.txt
> create mode 100644 Documentation/cxl/verbose-option.txt
> create mode 100644 cxl/lib/private.h
> create mode 100644 cxl/lib/libcxl.c
> create mode 100644 cxl/builtin.h
> create mode 100644 cxl/libcxl.h
> create mode 100644 cxl/cxl.c
> create mode 100644 cxl/list.c
> create mode 100644 Documentation/cxl/Makefile.am
> create mode 100644 cxl/Makefile.am
> create mode 100644 cxl/lib/Makefile.am
> create mode 100644 cxl/lib/libcxl.pc.in
> create mode 100644 cxl/lib/libcxl.sym
>
> diff --git a/Documentation/cxl/cxl-list.txt b/Documentation/cxl/cxl-list.txt
> new file mode 100644
> index 0000000..e761cfa
> --- /dev/null
> +++ b/Documentation/cxl/cxl-list.txt
> @@ -0,0 +1,64 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +cxl-list(1)
> +===========
> +
> +NAME
> +----
> +cxl-list - List CXL capable memory devices, and their attributes in json.
> +
> +SYNOPSIS
> +--------
> +[verse]
> +'cxl list' [<options>]
> +
> +Walk the CXL capable device hierarchy in the system and list all device
> +instances along with some of their major attributes.
> +
> +Options can be specified to limit the output to specific memdevs.
> +By default, 'cxl list' with no options is equivalent to:
> +[verse]
> +cxl list --memdevs
With the default change these last 4 lines can be trimmed.
> +
> +EXAMPLE
> +-------
> +----
> +# cxl list --memdevs
> +{
> + "memdev":"mem0",
> + "pmem_size":268435456,
> + "ram_size":0,
> +}
> +----
> +
> +OPTIONS
> +-------
> +-m::
> +--memdev=::
> + Specify a cxl memory device name to filter the listing. For example:
> +----
> +# cxl list --memdev=mem0
> +{
> + "memdev":"mem0",
> + "pmem_size":268435456,
> + "ram_size":0,
> +}
> +----
> +
> +-M::
> +--memdevs::
> + Include all CXL memory devices in the listing
The -m is a filter so I think this can be: s/all//
> +
> +-i::
> +--idle::
> + Include idle (not enabled / zero-sized) devices in the listing
> +
> +include::human-option.txt[]
> +
> +include::verbose-option.txt[]
> +
> +include::../copyright.txt[]
> +
> +SEE ALSO
> +--------
> +linkcxl:ndctl-list[1]
[..]
> diff --git a/cxl/list.c b/cxl/list.c
> new file mode 100644
> index 0000000..69201d9
> --- /dev/null
> +++ b/cxl/list.c
> @@ -0,0 +1,121 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/* Copyright (C) 2020-2021 Intel Corporation. All rights reserved. */
> +#include <stdio.h>
> +#include <errno.h>
> +#include <stdlib.h>
> +#include <unistd.h>
> +#include <limits.h>
> +#include <util/json.h>
> +#include <util/filter.h>
> +#include <json-c/json.h>
> +#include <cxl/libcxl.h>
> +#include <util/parse-options.h>
> +#include <ccan/array_size/array_size.h>
> +
> +static struct {
> + bool memdevs;
> + bool idle;
> + bool human;
> +} list;
> +
> +static unsigned long listopts_to_flags(void)
> +{
> + unsigned long flags = 0;
> +
> + if (list.idle)
> + flags |= UTIL_JSON_IDLE;
> + if (list.human)
> + flags |= UTIL_JSON_HUMAN;
> + return flags;
> +}
> +
> +static struct {
> + const char *memdev;
> +} param;
> +
> +static int did_fail;
> +
> +#define fail(fmt, ...) \
> +do { \
> + did_fail = 1; \
> + fprintf(stderr, "cxl-%s:%s:%d: " fmt, \
> + VERSION, __func__, __LINE__, ##__VA_ARGS__); \
> +} while (0)
> +
> +static int num_list_flags(void)
> +{
> + return list.memdevs;
> +}
> +
> +int cmd_list(int argc, const char **argv, struct cxl_ctx *ctx)
> +{
> + const struct option options[] = {
> + OPT_STRING('m', "memdev", ¶m.memdev, "memory device name",
> + "filter by CXL memory device name"),
> + OPT_BOOLEAN('M', "memdevs", &list.memdevs,
> + "include CXL memory device info"),
> + OPT_BOOLEAN('i', "idle", &list.idle, "include idle devices"),
> + OPT_BOOLEAN('u', "human", &list.human,
> + "use human friendly number formats "),
> + OPT_END(),
> + };
> + const char * const u[] = {
> + "cxl list [<options>]",
> + NULL
> + };
> + struct json_object *jdevs = NULL;
> + unsigned long list_flags;
> + struct cxl_memdev *memdev;
> + int i;
> +
> + argc = parse_options(argc, argv, options, u, 0);
> + for (i = 0; i < argc; i++)
> + error("unknown parameter \"%s\"\n", argv[i]);
> +
> + if (argc)
> + usage_with_options(u, options);
> +
> + if (num_list_flags() == 0) {
> + /*
> + * TODO: We likely want to list regions by default if nothing
> + * was explicitly asked for. But until we have region support,
> + * print this error asking for devices explicitly.
> + * Once region support is added, this TODO can be removed.
> + */
> + fprintf(stderr,
Should this be error() instead like the "unknown parameter" print above?
> + "please specify entities to list, e.g. using
> -m/-M\n");
Add a usage_with_options() call here to abort?