From patchwork Thu Mar 7 07:19:45 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dan Williams X-Patchwork-Id: 10842289 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 224B9139A for ; Thu, 7 Mar 2019 07:32:28 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 089252E3BA for ; Thu, 7 Mar 2019 07:32:28 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 06B872E50D; Thu, 7 Mar 2019 07:32:28 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from ml01.01.org (ml01.01.org [198.145.21.10]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 6C7312E4C0 for ; Thu, 7 Mar 2019 07:32:27 +0000 (UTC) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 2F3F6211D6163; Wed, 6 Mar 2019 23:32:27 -0800 (PST) X-Original-To: linux-nvdimm@lists.01.org Delivered-To: linux-nvdimm@lists.01.org Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=134.134.136.126; helo=mga18.intel.com; envelope-from=dan.j.williams@intel.com; receiver=linux-nvdimm@lists.01.org Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 66430211CFBFA for ; Wed, 6 Mar 2019 23:32:25 -0800 (PST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga106.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 06 Mar 2019 23:32:23 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.58,451,1544515200"; d="scan'208";a="149394181" Received: from dwillia2-desk3.jf.intel.com (HELO dwillia2-desk3.amr.corp.intel.com) ([10.54.39.16]) by fmsmga002.fm.intel.com with ESMTP; 06 Mar 2019 23:32:23 -0800 Subject: [ndctl PATCH] ndctl/list: Introduce region capability objects From: Dan Williams To: linux-nvdimm@lists.01.org Date: Wed, 06 Mar 2019 23:19:45 -0800 Message-ID: <155194318519.231776.375451851390009628.stgit@dwillia2-desk3.amr.corp.intel.com> User-Agent: StGit/0.18-2-gc94f MIME-Version: 1.0 X-BeenThere: linux-nvdimm@lists.01.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "Linux-nvdimm developer list." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: linux-nvdimm-bounces@lists.01.org Sender: "Linux-nvdimm" X-Virus-Scanned: ClamAV using ClamSMTP For common capabilities that a region can create provide a json object of the following form: "capabilities":[ { "mode":"sector", "sector_sizes":[ 512, 520, 528, 4096, 4104, 4160, 4224 ] }, { "mode":"fsdax", "alignments":[ 4096, 2097152, 1073741824 ] }, { "mode":"devdax", "alignments":[ 4096, 2097152, 1073741824 ] } ] This replaces the "supported_alignments" and "supported sector sizes" fields which ended up being too repetitive at the namespace level. Cc: Oliver O'Halloran Signed-off-by: Dan Williams --- Documentation/ndctl/ndctl-list.txt | 9 +++- ndctl/list.c | 12 +++++ util/json.c | 89 +++++++++++++++++++++++++++++------- util/json.h | 2 + 4 files changed, 93 insertions(+), 19 deletions(-) diff --git a/Documentation/ndctl/ndctl-list.txt b/Documentation/ndctl/ndctl-list.txt index bdd69add9f22..80ad6100060f 100644 --- a/Documentation/ndctl/ndctl-list.txt +++ b/Documentation/ndctl/ndctl-list.txt @@ -175,6 +175,12 @@ include::xable-region-options.txt[] --idle:: Include idle (not enabled) devices in the listing +-C:: +--capabilities:: + Include region capabilities in the listing, i.e. supported + namespace modes and variable properties like sector sizes and + alignments. + -M:: --media-errors:: Include media errors (badblocks) in the listing. Note that the @@ -222,7 +228,8 @@ include::xable-region-options.txt[] Everything '-v' provides, plus automatically enable --dimms, --buses, and --regions. + - *-vvv* - Everything '-vv' provides, plus --health, --idle, and --firmware. + Everything '-vv' provides, plus --health, --capabilities, + --idle, and --firmware. include::human-option.txt[] diff --git a/ndctl/list.c b/ndctl/list.c index 506404db11b0..1c3e34d58ddb 100644 --- a/ndctl/list.c +++ b/ndctl/list.c @@ -36,6 +36,7 @@ static struct { bool media_errors; bool human; bool firmware; + bool capabilities; int verbose; } list; @@ -53,6 +54,8 @@ static unsigned long listopts_to_flags(void) flags |= UTIL_JSON_HUMAN; if (list.verbose) flags |= UTIL_JSON_VERBOSE; + if (list.capabilities) + flags |= UTIL_JSON_CAPABILITIES; return flags; } @@ -186,6 +189,12 @@ static struct json_object *region_to_json(struct ndctl_region *region, if ((flags & UTIL_JSON_MEDIA_ERRORS) && jbbs) json_object_object_add(jregion, "badblocks", jbbs); + if (flags & UTIL_JSON_CAPABILITIES) { + jobj = util_region_capabilities_to_json(region); + if (jobj) + json_object_object_add(jregion, "capabilities", jobj); + } + pd = ndctl_region_get_persistence_domain(region); switch (pd) { case PERSISTENCE_CPU_CACHE: @@ -450,6 +459,8 @@ int cmd_list(int argc, const char **argv, struct ndctl_ctx *ctx) "include namespace info (default)"), OPT_BOOLEAN('X', "device-dax", &list.dax, "include device-dax info"), + OPT_BOOLEAN('C', "capabilities", &list.capabilities, + "include region capability info"), OPT_BOOLEAN('i', "idle", &list.idle, "include idle devices"), OPT_BOOLEAN('M', "media-errors", &list.media_errors, "include media errors"), @@ -487,6 +498,7 @@ int cmd_list(int argc, const char **argv, struct ndctl_ctx *ctx) list.idle = true; list.firmware = true; list.health = true; + list.capabilities = true; case 2: list.dimms = true; list.buses = true; diff --git a/util/json.c b/util/json.c index c732f1b77522..babdc8c47565 100644 --- a/util/json.c +++ b/util/json.c @@ -321,7 +321,7 @@ struct json_object *util_daxctl_devs_to_list(struct daxctl_region *region, } #define _SZ(get_max, get_elem, type) \ -static struct json_object *type##_build_size_array(struct type *arg) \ +static struct json_object *util_##type##_build_size_array(struct ndctl_##type *arg) \ { \ struct json_object *arr = json_object_new_array(); \ int i; \ @@ -346,11 +346,78 @@ err: \ return NULL; \ } #define SZ(type, kind) _SZ(ndctl_##type##_get_num_##kind##s, \ - ndctl_##type##_get_supported_##kind, ndctl_##type) + ndctl_##type##_get_supported_##kind, type) SZ(pfn, alignment) SZ(dax, alignment) SZ(btt, sector_size) -//SZ(namespace, sector_size) + +struct json_object *util_region_capabilities_to_json(struct ndctl_region *region) +{ + struct json_object *jcaps, *jcap, *jobj; + struct ndctl_btt *btt = ndctl_region_get_btt_seed(region); + struct ndctl_pfn *pfn = ndctl_region_get_pfn_seed(region); + struct ndctl_dax *dax = ndctl_region_get_dax_seed(region); + + if (!btt || !pfn || !dax) + return NULL; + + jcaps = json_object_new_array(); + if (!jcaps) + return NULL; + + if (btt) { + jcap = json_object_new_object(); + if (!jcap) + goto err; + json_object_array_add(jcaps, jcap); + + jobj = json_object_new_string("sector"); + if (!jobj) + goto err; + json_object_object_add(jcap, "mode", jobj); + jobj = util_btt_build_size_array(btt); + if (!jobj) + goto err; + json_object_object_add(jcap, "sector_sizes", jobj); + } + + if (pfn) { + jcap = json_object_new_object(); + if (!jcap) + goto err; + json_object_array_add(jcaps, jcap); + + jobj = json_object_new_string("fsdax"); + if (!jobj) + goto err; + json_object_object_add(jcap, "mode", jobj); + jobj = util_pfn_build_size_array(pfn); + if (!jobj) + goto err; + json_object_object_add(jcap, "alignments", jobj); + } + + if (dax) { + jcap = json_object_new_object(); + if (!jcap) + goto err; + json_object_array_add(jcaps, jcap); + + jobj = json_object_new_string("devdax"); + if (!jobj) + goto err; + json_object_object_add(jcap, "mode", jobj); + jobj = util_dax_build_size_array(dax); + if (!jobj) + goto err; + json_object_object_add(jcap, "alignments", jobj); + } + + return jcaps; +err: + json_object_put(jcaps); + return NULL; +} struct json_object *util_daxctl_region_to_json(struct daxctl_region *region, const char *ident, unsigned long flags) @@ -788,7 +855,7 @@ struct json_object *util_namespace_to_json(struct ndctl_namespace *ndns, { struct json_object *jndns = json_object_new_object(); enum ndctl_pfn_loc loc = NDCTL_PFN_LOC_NONE; - struct json_object *jobj, *jbbs = NULL, *size_array = NULL; + struct json_object *jobj, *jbbs = NULL; const char *locations[] = { [NDCTL_PFN_LOC_NONE] = "none", [NDCTL_PFN_LOC_RAM] = "mem", @@ -798,7 +865,6 @@ struct json_object *util_namespace_to_json(struct ndctl_namespace *ndns, unsigned int sector_size = UINT_MAX; enum ndctl_namespace_mode mode; const char *bdev = NULL, *name; - const char *size_array_name; unsigned int bb_count = 0; struct ndctl_btt *btt; struct ndctl_pfn *pfn; @@ -986,19 +1052,6 @@ struct json_object *util_namespace_to_json(struct ndctl_namespace *ndns, json_object_object_add(jndns, "numa_node", jobj); } - if (pfn) { - size_array_name = "supported_alignments"; - size_array = ndctl_pfn_build_size_array(pfn); - } else if (dax) { - size_array_name = "supported_alignments"; - size_array = ndctl_dax_build_size_array(dax); - } else if (btt) { - size_array_name = "supported sector sizes"; - size_array = ndctl_btt_build_size_array(btt); - } - if (size_array && flags & UTIL_JSON_VERBOSE) - json_object_object_add(jndns, size_array_name, size_array); - if (pfn) jbbs = util_pfn_badblocks_to_json(pfn, &bb_count, flags); else if (dax) diff --git a/util/json.h b/util/json.h index e292973dbbbf..7c3f64932cec 100644 --- a/util/json.h +++ b/util/json.h @@ -24,6 +24,7 @@ enum util_json_flags { UTIL_JSON_DAX_DEVS = (1 << 3), UTIL_JSON_HUMAN = (1 << 4), UTIL_JSON_VERBOSE = (1 << 5), + UTIL_JSON_CAPABILITIES = (1 << 6), }; struct json_object; @@ -56,4 +57,5 @@ struct json_object *util_json_object_hex(unsigned long long val, struct json_object *util_dimm_health_to_json(struct ndctl_dimm *dimm); struct json_object *util_dimm_firmware_to_json(struct ndctl_dimm *dimm, unsigned long flags); +struct json_object *util_region_capabilities_to_json(struct ndctl_region *region); #endif /* __NDCTL_JSON_H__ */