anitazha / rpms / ndctl

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