ndctl/0094-cxl-list-Introduce-cxl...

293 lines
7.8 KiB
Diff

From f833845ce72490e4c80b3ccc9972d5329f69a381 Mon Sep 17 00:00:00 2001
From: Dan Williams <dan.j.williams@intel.com>
Date: Sun, 23 Jan 2022 16:52:31 -0800
Subject: [PATCH 094/217] cxl/list: Introduce cxl_filter_walk()
In preparation for introducing more objects and filtering options for 'cxl
list' introduce cxl_filter_walk() to centralize CXL topology walks. It
fills the same role as ndctl_filter_walk() as a way to distribute topology
interrogation beyond 'cxl list' to other commands, and serve as the
template for CXL object hierarchy in JSON output payloads.
Use the common dbg() logger for log messages.
Link: https://lore.kernel.org/r/164298555121.3021641.16127840206319352254.stgit@dwillia2-desk3.amr.corp.intel.com
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
---
Documentation/cxl/cxl-list.txt | 2 +
cxl/filter.c | 50 ++++++++++++++++
cxl/filter.h | 18 +++++-
cxl/list.c | 102 +++++++--------------------------
cxl/meson.build | 1 +
5 files changed, 90 insertions(+), 83 deletions(-)
diff --git a/Documentation/cxl/cxl-list.txt b/Documentation/cxl/cxl-list.txt
index 686e0ea..4d409ba 100644
--- a/Documentation/cxl/cxl-list.txt
+++ b/Documentation/cxl/cxl-list.txt
@@ -15,6 +15,8 @@ SYNOPSIS
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 objects.
+
EXAMPLE
-------
----
diff --git a/cxl/filter.c b/cxl/filter.c
index 405b653..d1ff4b6 100644
--- a/cxl/filter.c
+++ b/cxl/filter.c
@@ -1,10 +1,16 @@
// SPDX-License-Identifier: GPL-2.0
// Copyright (C) 2015-2020 Intel Corporation. All rights reserved.
+#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
+#include <util/log.h>
+#include <util/json.h>
#include <cxl/libcxl.h>
+#include <json-c/json.h>
+
#include "filter.h"
+#include "json.h"
static const char *which_sep(const char *filter)
{
@@ -48,3 +54,47 @@ struct cxl_memdev *util_cxl_memdev_filter(struct cxl_memdev *memdev,
return memdev;
return NULL;
}
+
+static unsigned long params_to_flags(struct cxl_filter_params *param)
+{
+ unsigned long flags = 0;
+
+ if (param->idle)
+ flags |= UTIL_JSON_IDLE;
+ if (param->human)
+ flags |= UTIL_JSON_HUMAN;
+ if (param->health)
+ flags |= UTIL_JSON_HEALTH;
+ return flags;
+}
+
+int cxl_filter_walk(struct cxl_ctx *ctx, struct cxl_filter_params *p)
+{
+ struct json_object *jplatform = json_object_new_array();
+ unsigned long flags = params_to_flags(p);
+ struct cxl_memdev *memdev;
+
+ if (!jplatform) {
+ dbg(p, "platform object allocation failure\n");
+ return -ENOMEM;
+ }
+
+ cxl_memdev_foreach(ctx, memdev) {
+ struct json_object *jdev;
+
+ if (!util_cxl_memdev_filter(memdev, p->memdev_filter))
+ continue;
+ if (p->memdevs) {
+ jdev = util_cxl_memdev_to_json(memdev, flags);
+ if (!jdev) {
+ dbg(p, "memdev object allocation failure\n");
+ continue;
+ }
+ json_object_array_add(jplatform, jdev);
+ }
+ }
+
+ util_display_json_array(stdout, jplatform, flags);
+
+ return 0;
+}
diff --git a/cxl/filter.h b/cxl/filter.h
index da80033..664b74b 100644
--- a/cxl/filter.h
+++ b/cxl/filter.h
@@ -1,7 +1,21 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright (C) 2015-2020 Intel Corporation. All rights reserved. */
+/* Copyright (C) 2021 Intel Corporation. All rights reserved. */
#ifndef _CXL_UTIL_FILTER_H_
#define _CXL_UTIL_FILTER_H_
+
+#include <stdbool.h>
+#include <util/log.h>
+
+struct cxl_filter_params {
+ const char *memdev_filter;
+ bool memdevs;
+ bool idle;
+ bool human;
+ bool health;
+ struct log_ctx ctx;
+};
+
struct cxl_memdev *util_cxl_memdev_filter(struct cxl_memdev *memdev,
- const char *ident);
+ const char *ident);
+int cxl_filter_walk(struct cxl_ctx *ctx, struct cxl_filter_params *param);
#endif /* _CXL_UTIL_FILTER_H_ */
diff --git a/cxl/list.c b/cxl/list.c
index 7f7a04d..1730307 100644
--- a/cxl/list.c
+++ b/cxl/list.c
@@ -9,60 +9,27 @@
#include <json-c/json.h>
#include <cxl/libcxl.h>
#include <util/parse-options.h>
-#include <ccan/array_size/array_size.h>
-#include "json.h"
#include "filter.h"
-static struct {
- bool memdevs;
- bool idle;
- bool human;
- bool health;
-} 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;
- if (list.health)
- flags |= UTIL_JSON_HEALTH;
- 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 struct cxl_filter_params param;
static int num_list_flags(void)
{
- return list.memdevs;
+ return param.memdevs;
}
int cmd_list(int argc, const char **argv, struct cxl_ctx *ctx)
{
const struct option options[] = {
- OPT_STRING('m', "memdev", &param.memdev, "memory device name",
+ OPT_STRING('m', "memdev", &param.memdev_filter, "memory device name",
"filter by CXL memory device name"),
- OPT_BOOLEAN('M', "memdevs", &list.memdevs,
+ OPT_BOOLEAN('M', "memdevs", &param.memdevs,
"include CXL memory device info"),
- OPT_BOOLEAN('i', "idle", &list.idle, "include idle devices"),
- OPT_BOOLEAN('u', "human", &list.human,
+ OPT_BOOLEAN('i', "idle", &param.idle, "include disabled devices"),
+ OPT_BOOLEAN('u', "human", &param.human,
"use human friendly number formats "),
- OPT_BOOLEAN('H', "health", &list.health,
+ OPT_BOOLEAN('H', "health", &param.health,
"include memory device health information "),
OPT_END(),
};
@@ -70,9 +37,6 @@ int cmd_list(int argc, const char **argv, struct cxl_ctx *ctx)
"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);
@@ -83,46 +47,22 @@ int cmd_list(int argc, const char **argv, struct cxl_ctx *ctx)
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.
- */
- error("please specify entities to list, e.g. using -m/-M\n");
- usage_with_options(u, options);
- }
-
- list_flags = listopts_to_flags();
-
- cxl_memdev_foreach(ctx, memdev) {
- struct json_object *jdev = NULL;
-
- if (!util_cxl_memdev_filter(memdev, param.memdev))
- continue;
-
- if (list.memdevs) {
- if (!jdevs) {
- jdevs = json_object_new_array();
- if (!jdevs) {
- fail("\n");
- continue;
- }
- }
-
- jdev = util_cxl_memdev_to_json(memdev, list_flags);
- if (!jdev) {
- fail("\n");
- continue;
- }
- json_object_array_add(jdevs, jdev);
+ if (param.memdev_filter)
+ param.memdevs = true;
+ else {
+ /*
+ * 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.
+ */
+ error("please specify entities to list, e.g. using -m/-M\n");
+ usage_with_options(u, options);
}
}
- if (jdevs)
- util_display_json_array(stdout, jdevs, list_flags);
+ log_init(&param.ctx, "cxl list", "CXL_LIST_LOG");
- if (did_fail)
- return -ENOMEM;
- return 0;
+ return cxl_filter_walk(ctx, &param);
}
diff --git a/cxl/meson.build b/cxl/meson.build
index 805924b..fc7ee71 100644
--- a/cxl/meson.build
+++ b/cxl/meson.build
@@ -3,6 +3,7 @@ cxl_src = [
'list.c',
'memdev.c',
'../util/json.c',
+ '../util/log.c',
'json.c',
'filter.c',
]
--
2.27.0