293 lines
7.8 KiB
Diff
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", ¶m.memdev, "memory device name",
|
|
+ OPT_STRING('m', "memdev", ¶m.memdev_filter, "memory device name",
|
|
"filter by CXL memory device name"),
|
|
- OPT_BOOLEAN('M', "memdevs", &list.memdevs,
|
|
+ OPT_BOOLEAN('M', "memdevs", ¶m.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", ¶m.idle, "include disabled devices"),
|
|
+ OPT_BOOLEAN('u', "human", ¶m.human,
|
|
"use human friendly number formats "),
|
|
- OPT_BOOLEAN('H', "health", &list.health,
|
|
+ OPT_BOOLEAN('H', "health", ¶m.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(¶m.ctx, "cxl list", "CXL_LIST_LOG");
|
|
|
|
- if (did_fail)
|
|
- return -ENOMEM;
|
|
- return 0;
|
|
+ return cxl_filter_walk(ctx, ¶m);
|
|
}
|
|
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
|
|
|