From patchwork Wed Feb 6 03:13:23 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dexuan Cui X-Patchwork-Id: 10798761 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 046F113B5 for ; Wed, 6 Feb 2019 03:13:33 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DF2072C1E5 for ; Wed, 6 Feb 2019 03:13:32 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id CDAA62A92E; Wed, 6 Feb 2019 03:13:32 +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.7 required=2.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,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 A33802A92E for ; Wed, 6 Feb 2019 03:13:31 +0000 (UTC) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 5FDE2211CA2CE; Tue, 5 Feb 2019 19:13:31 -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=40.107.131.118; helo=apc01-sg2-obe.outbound.protection.outlook.com; envelope-from=decui@microsoft.com; receiver=linux-nvdimm@lists.01.org Received: from APC01-SG2-obe.outbound.protection.outlook.com (mail-eopbgr1310118.outbound.protection.outlook.com [40.107.131.118]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 47FFA211CA2C9 for ; Tue, 5 Feb 2019 19:13:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=He6jun57EygU4L3yBFvh5EXmaSEOrr4rV3S5oWo2284=; b=b4Fa1lpqMRN/tzwyeo7x/Rpgq+Ir4923YA7kMiyXhp4a8PUTt2yU2A29TTiR6TRXdRkLnFiRgan4u2ptftEmK7dLpmJhsPZRudFzXyDMnXODYQcU5rTILHMighW9QSko7v9vxf1kVS50xCRmnmSoKHner7tdYv7sIL5Gbzw6z90= Received: from PU1P153MB0169.APCP153.PROD.OUTLOOK.COM (10.170.189.13) by PU1P153MB0155.APCP153.PROD.OUTLOOK.COM (10.170.189.11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1622.3; Wed, 6 Feb 2019 03:13:23 +0000 Received: from PU1P153MB0169.APCP153.PROD.OUTLOOK.COM ([fe80::7822:a20:e63c:de2f]) by PU1P153MB0169.APCP153.PROD.OUTLOOK.COM ([fe80::7822:a20:e63c:de2f%9]) with mapi id 15.20.1622.006; Wed, 6 Feb 2019 03:13:23 +0000 From: Dexuan Cui To: Dan Williams , "linux-nvdimm@lists.01.org" Subject: [ndctl PATCH 1/2] libndctl: add support for NVDIMM_FAMILY_HYPERV's _DSM Function 1 Thread-Topic: [ndctl PATCH 1/2] libndctl: add support for NVDIMM_FAMILY_HYPERV's _DSM Function 1 Thread-Index: AdS9ydvoBPXJaodnTWSOHwsSzuimUg== Date: Wed, 6 Feb 2019 03:13:23 +0000 Message-ID: Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: msip_labels: MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_Enabled=True; MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_SiteId=72f988bf-86f1-41af-91ab-2d7cd011db47; MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_Owner=decui@microsoft.com; MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_SetDate=2019-02-06T03:13:20.9367578Z; MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_Name=General; MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_Application=Microsoft Azure Information Protection; MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_ActionId=26380f99-d29f-46d1-9e67-886cbb6569c2; MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_Extended_MSFT_Method=Automatic x-originating-ip: [2601:600:a280:1760:5896:cf8a:cefe:fd7] x-ms-publictraffictype: Email x-microsoft-exchange-diagnostics: 1; PU1P153MB0155; 6:K2LGetuVG6d/AXWExziu34X0wDn01hqkKwmUJoHn36qroraeUVqJwtKDTNSJxv9euiJb34aK1lC9W3P2HFIOzUOAlwTuLS6WXrTjphWh1aeYdgIvobTCI0QFV7wdnFOCRinJehr7NW1BhqnK3e3jrwa8rRfBhdPKl877sS2Q0Ass4rdIs/0cltHSRxkuCfn8VIDa1BXNNJ1ORNhyKNp1pu56lVXP9q3W9oiVoTpVQlZYS8GaGZ6qxFjwXTk3fxHWBfLWCvDgBxxxGeyDhULZyY1o4vbSSvA1VwSd2fj6AeD26aRN+QXdLQ9B83RHZDdBmedUxseeEmeXq9a9/ky8sTLBp4ffXXAM9nXO6+NbhkEegjIxZLbZAAs1rVp1Z3RRCExe8TZOYKP8gUCxL4Idzyn2YYQcS2Cf+uEDQqga2d+GCYfCsmP+xRilso2wPKKZMlSaQyrEt0BeA4M/baw6tw==; 5:RtS2UtVEm36yGKhid0Kgj9lY9fIyeIwpvjIhxHbNMu0Cm1hLrO50clS8h7VI8xTss8N5am0HU0+ar7jP74hkQ84+4EMs4xCOan3bL1+qJil116qx9/txVXZ6L5FIpca62WEi9cA00rzsXPpFWjuyq7ldvxO5EVSo0M0DdtchSJDiXo8b1czACiHhttJiLAhCzPbd5oog8kEaOrDAeITGjg==; 7:6tUl8hZFK+pBmpKy8nmuVWZtLPrFWllUnQIoVaeL3+hBqbfR40Qt0JrB5XziUygDVNbQsBZZlBhSVk49mJWa9iID6VISteBsHKZV/mHzJKhFG21za7SV5z73ZIWaGSOTFuwwucZ3isW/B+7M733DAw== x-ms-office365-filtering-correlation-id: 8ba482a5-e5a8-449b-6f2a-08d68be10de5 x-ms-office365-filtering-ht: Tenant x-microsoft-antispam: BCL:0; PCL:0; RULEID:(2390118)(7020095)(4652040)(8989299)(5600110)(711020)(4605077)(4618075)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(2017052603328)(7193020); SRVR:PU1P153MB0155; x-ms-traffictypediagnostic: PU1P153MB0155: x-ms-exchange-purlcount: 1 x-microsoft-antispam-prvs: x-forefront-prvs: 0940A19703 x-forefront-antispam-report: SFV:NSPM; SFS:(10019020)(136003)(396003)(366004)(39860400002)(346002)(376002)(189003)(199004)(53936002)(25786009)(46003)(9686003)(110136005)(476003)(10290500003)(6306002)(966005)(2501003)(22452003)(486006)(55016002)(86362001)(256004)(14444005)(305945005)(7736002)(7696005)(478600001)(2906002)(99286004)(4326008)(14454004)(68736007)(8990500004)(81156014)(81166006)(86612001)(71200400001)(71190400001)(8936002)(33656002)(102836004)(6506007)(74316002)(6346003)(6436002)(186003)(316002)(97736004)(10090500001)(106356001)(105586002)(6116002)(107886003)(8676002)(2004002); DIR:OUT; SFP:1102; SCL:1; SRVR:PU1P153MB0155; H:PU1P153MB0169.APCP153.PROD.OUTLOOK.COM; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; MX:1; A:1; received-spf: None (protection.outlook.com: microsoft.com does not designate permitted sender hosts) authentication-results: spf=none (sender IP is ) smtp.mailfrom=decui@microsoft.com; x-ms-exchange-senderadcheck: 1 x-microsoft-antispam-message-info: tNr+gEVqbCHxmBq3taY2R/oX0WAmNKZBNoKgpOUPXgddXtBeZnwPgaIuhh8iIG+ZkDFFdoQ5xnnADK9cwsPakfwx+9k9EFzhrdwIgl0Qy6eijlPZLc4zf4mIsRs8grxaASDaOzimkz1hekJxCJEEAtmz4ukqq57Lxw2XQYI2HZVrRLFOlxRDYdHFxUi1VdkgbUaQ3vtay0Y2uAKhzXW0N3lhuWIcBF3ULUWIRAxXN/3cYY7zN2AKI5veRmM8g0s84OQ5kmxrPu0zuqbnqP4jDAUwHmgZdBAmDNfsqG8cuLVa7Vc/SZ7wKZaD/zX4Gi5jH9eYvDPHjKxUKarxykDBMq0lD/9Cww9ZfIWCh2JoPLkq3uruvy7HQvXosmV0CeumiFVKr6DR/f0EVwpdfzJNXVG6sHfEmNLweum4g6k52Rk= MIME-Version: 1.0 X-OriginatorOrg: microsoft.com X-MS-Exchange-CrossTenant-Network-Message-Id: 8ba482a5-e5a8-449b-6f2a-08d68be10de5 X-MS-Exchange-CrossTenant-originalarrivaltime: 06 Feb 2019 03:13:23.1849 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 72f988bf-86f1-41af-91ab-2d7cd011db47 X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-Transport-CrossTenantHeadersStamped: PU1P153MB0155 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: , Cc: Michael Kelley Errors-To: linux-nvdimm-bounces@lists.01.org Sender: "Linux-nvdimm" X-Virus-Scanned: ClamAV using ClamSMTP This patch retrieves the health info by Hyper-V _DSM method Function 1: Get Health Information (Function Index 1) See http://www.uefi.org/RFIC_LIST ("Virtual NVDIMM 0x1901"). Now "ndctl list --dimms --health --idle" can show a line "health_state":"ok", e.g. { "dev":"nmem0", "id":"04d5-01-1701-00000000", "handle":0, "phys_id":0, "health":{ "health_state":"ok" } } If there is an error with the NVDIMM, the "ok" will be replaced with "unknown", "fatal", "critical", or "non-critical". Hyper-V also supports "Get Unsafe Shutdown Count (Function Index 2)", but unluckily util_dimm_health_to_json() only submits *one* command, so we don't have a chance to call Function 2 here, and hence we can't show a line "shutdown_count" in the output. If a user in a Linux virtual machine running on Hyper-V is interested in the Unsafe Shutdown Count, please directly run: "cat /sys/bus/nd/devices/nmem*/nfit/dirty_shutdown" (there is a pending patch submitted to the kernel for this sysfs node). Signed-off-by: Dexuan Cui --- ndctl/lib/Makefile.am | 1 + ndctl/lib/hyperv.c | 129 ++++++++++++++++++++++++++++++++++++++++++ ndctl/lib/hyperv.h | 51 +++++++++++++++++ ndctl/lib/libndctl.c | 2 + ndctl/lib/private.h | 3 + ndctl/ndctl.h | 1 + 6 files changed, 187 insertions(+) create mode 100644 ndctl/lib/hyperv.c create mode 100644 ndctl/lib/hyperv.h diff --git a/ndctl/lib/Makefile.am b/ndctl/lib/Makefile.am index 7797039..fb75fda 100644 --- a/ndctl/lib/Makefile.am +++ b/ndctl/lib/Makefile.am @@ -20,6 +20,7 @@ libndctl_la_SOURCES =\ intel.c \ hpe1.c \ msft.c \ + hyperv.c \ ars.c \ firmware.c \ libndctl.c diff --git a/ndctl/lib/hyperv.c b/ndctl/lib/hyperv.c new file mode 100644 index 0000000..b303d50 --- /dev/null +++ b/ndctl/lib/hyperv.c @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2019, Microsoft Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU Lesser General Public License, + * version 2.1, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for + * more details. + */ +#include +#include +#include +#include +#include +#include "private.h" +#include "hyperv.h" + +#define CMD_HYPERV(_c) ((_c)->hyperv) +#define CMD_HYPERV_STATUS(_c) (CMD_HYPERV(_c)->u.status) +#define CMD_HYPERV_SMART_DATA(_c) (CMD_HYPERV(_c)->u.smart.data) + +static struct ndctl_cmd *hyperv_dimm_cmd_new_smart(struct ndctl_dimm *dimm) +{ + struct ndctl_bus *bus = ndctl_dimm_get_bus(dimm); + struct ndctl_ctx *ctx = ndctl_bus_get_ctx(bus); + struct ndctl_cmd *cmd; + size_t size; + struct nd_pkg_hyperv *hyperv; + + if (!ndctl_dimm_is_cmd_supported(dimm, ND_CMD_CALL)) { + dbg(ctx, "unsupported cmd\n"); + return NULL; + } + + if (test_dimm_dsm(dimm, ND_HYPERV_CMD_GET_HEALTH_INFO) == + DIMM_DSM_UNSUPPORTED) { + dbg(ctx, "unsupported function\n"); + return NULL; + } + + size = sizeof(*cmd) + sizeof(struct nd_pkg_hyperv); + cmd = calloc(1, size); + if (!cmd) + return NULL; + + cmd->dimm = dimm; + ndctl_cmd_ref(cmd); + cmd->type = ND_CMD_CALL; + cmd->size = size; + cmd->status = 1; + + hyperv = CMD_HYPERV(cmd); + hyperv->gen.nd_family = NVDIMM_FAMILY_HYPERV; + hyperv->gen.nd_command = ND_HYPERV_CMD_GET_HEALTH_INFO; + hyperv->gen.nd_fw_size = 0; + hyperv->gen.nd_size_in = offsetof(struct nd_hyperv_smart, status); + hyperv->gen.nd_size_out = sizeof(hyperv->u.smart); + hyperv->u.smart.status = 0; + + cmd->firmware_status = &hyperv->u.smart.status; + + return cmd; +} + +static int hyperv_smart_valid(struct ndctl_cmd *cmd) +{ + if (cmd->type != ND_CMD_CALL || + cmd->size != sizeof(*cmd) + sizeof(struct nd_pkg_hyperv) || + CMD_HYPERV(cmd)->gen.nd_family != NVDIMM_FAMILY_HYPERV || + CMD_HYPERV(cmd)->gen.nd_command != ND_HYPERV_CMD_GET_HEALTH_INFO || + cmd->status != 0 || + CMD_HYPERV_STATUS(cmd) != 0) + return cmd->status < 0 ? cmd->status : -EINVAL; + return 0; +} + +static int hyperv_cmd_xlat_firmware_status(struct ndctl_cmd *cmd) +{ + return CMD_HYPERV_STATUS(cmd) == 0 ? 0 : -EINVAL; +} + +static unsigned int hyperv_cmd_smart_get_flags(struct ndctl_cmd *cmd) +{ + int rc; + + rc = hyperv_smart_valid(cmd); + if (rc < 0) { + errno = -rc; + return 0; + } + + return ND_SMART_HEALTH_VALID; +} + +static unsigned int hyperv_cmd_smart_get_health(struct ndctl_cmd *cmd) +{ + unsigned int health = 0; + __u32 num; + int rc; + + rc = hyperv_smart_valid(cmd); + if (rc < 0) { + errno = -rc; + return UINT_MAX; + } + + num = CMD_HYPERV_SMART_DATA(cmd)->health & 0x3F; + + if (num & (BIT(0) | BIT(1))) + health |= ND_SMART_CRITICAL_HEALTH; + + if (num & BIT(2)) + health |= ND_SMART_FATAL_HEALTH; + + if (num & (BIT(3) | BIT(4) | BIT(5))) + health |= ND_SMART_NON_CRITICAL_HEALTH; + + return health; +} + +struct ndctl_dimm_ops * const hyperv_dimm_ops = &(struct ndctl_dimm_ops) { + .new_smart = hyperv_dimm_cmd_new_smart, + .smart_get_flags = hyperv_cmd_smart_get_flags, + .smart_get_health = hyperv_cmd_smart_get_health, + .xlat_firmware_status = hyperv_cmd_xlat_firmware_status, +}; diff --git a/ndctl/lib/hyperv.h b/ndctl/lib/hyperv.h new file mode 100644 index 0000000..8e55a97 --- /dev/null +++ b/ndctl/lib/hyperv.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2019, Microsoft Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU Lesser General Public License, + * version 2.1, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for + * more details. + */ +#ifndef __NDCTL_HYPERV_H__ +#define __NDCTL_HYPERV_H__ + +/* See http://www.uefi.org/RFIC_LIST ("Virtual NVDIMM 0x1901") */ +enum { + ND_HYPERV_CMD_QUERY = 0, + + /* non-root commands */ + ND_HYPERV_CMD_GET_HEALTH_INFO = 1, +}; + +/* + * This is actually Function 1's data, + * This is the closest I can find to match the "smart". + * Hyper-V _DSM methods don't have a smart function. + */ +struct nd_hyperv_smart_data { + __u32 health; +} __attribute__((packed)); + +struct nd_hyperv_smart { + __u32 status; + union { + __u8 buf[4]; + struct nd_hyperv_smart_data data[0]; + }; +} __attribute__((packed)); + +union nd_hyperv_cmd { + __u32 status; + struct nd_hyperv_smart smart; +} __attribute__((packed)); + +struct nd_pkg_hyperv { + struct nd_cmd_pkg gen; + union nd_hyperv_cmd u; +} __attribute__((packed)); + +#endif /* __NDCTL_HYPERV_H__ */ diff --git a/ndctl/lib/libndctl.c b/ndctl/lib/libndctl.c index c9e2875..48bdb27 100644 --- a/ndctl/lib/libndctl.c +++ b/ndctl/lib/libndctl.c @@ -1492,6 +1492,8 @@ static void *add_dimm(void *parent, int id, const char *dimm_base) dimm->ops = hpe1_dimm_ops; if (dimm->cmd_family == NVDIMM_FAMILY_MSFT) dimm->ops = msft_dimm_ops; + if (dimm->cmd_family == NVDIMM_FAMILY_HYPERV) + dimm->ops = hyperv_dimm_ops; sprintf(path, "%s/nfit/dsm_mask", dimm_base); if (sysfs_read_attr(ctx, path, buf) == 0) diff --git a/ndctl/lib/private.h b/ndctl/lib/private.h index a387b0b..a9d35c5 100644 --- a/ndctl/lib/private.h +++ b/ndctl/lib/private.h @@ -31,6 +31,7 @@ #include "intel.h" #include "hpe1.h" #include "msft.h" +#include "hyperv.h" struct nvdimm_data { struct ndctl_cmd *cmd_read; @@ -270,6 +271,7 @@ struct ndctl_cmd { struct nd_cmd_pkg pkg[0]; struct ndn_pkg_hpe1 hpe1[0]; struct ndn_pkg_msft msft[0]; + struct nd_pkg_hyperv hyperv[0]; struct nd_pkg_intel intel[0]; struct nd_cmd_get_config_size get_size[0]; struct nd_cmd_get_config_data_hdr get_data[0]; @@ -344,6 +346,7 @@ struct ndctl_dimm_ops { struct ndctl_dimm_ops * const intel_dimm_ops; struct ndctl_dimm_ops * const hpe1_dimm_ops; struct ndctl_dimm_ops * const msft_dimm_ops; +struct ndctl_dimm_ops * const hyperv_dimm_ops; static inline struct ndctl_bus *cmd_to_bus(struct ndctl_cmd *cmd) { diff --git a/ndctl/ndctl.h b/ndctl/ndctl.h index c6aaa4c..008f81c 100644 --- a/ndctl/ndctl.h +++ b/ndctl/ndctl.h @@ -262,6 +262,7 @@ struct nd_cmd_pkg { #define NVDIMM_FAMILY_HPE1 1 #define NVDIMM_FAMILY_HPE2 2 #define NVDIMM_FAMILY_MSFT 3 +#define NVDIMM_FAMILY_HYPERV 4 #define ND_IOCTL_CALL _IOWR(ND_IOCTL, ND_CMD_CALL,\ struct nd_cmd_pkg) From patchwork Wed Feb 6 03:15:24 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dexuan Cui X-Patchwork-Id: 10798763 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 5913613BF for ; Wed, 6 Feb 2019 03:15:31 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3AA112C1E5 for ; Wed, 6 Feb 2019 03:15:31 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2EED92C21A; Wed, 6 Feb 2019 03:15:31 +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.7 required=2.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,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 AEE7F2C207 for ; Wed, 6 Feb 2019 03:15:30 +0000 (UTC) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 9AF7D211CA2D1; Tue, 5 Feb 2019 19:15:30 -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=40.107.131.101; helo=apc01-sg2-obe.outbound.protection.outlook.com; envelope-from=decui@microsoft.com; receiver=linux-nvdimm@lists.01.org Received: from APC01-SG2-obe.outbound.protection.outlook.com (mail-eopbgr1310101.outbound.protection.outlook.com [40.107.131.101]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id D0BED211CA2C9 for ; Tue, 5 Feb 2019 19:15:29 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=/bmgAHqAFIQEe686K5KNHLp2NtF+eKSiFiU30JqluxY=; b=czzyLQdwMJe7RfXMP/eNxldrPstG2dWDExGDu/F1defww1knp2q1DIDW9XgN064Yi5xiHyy8io70YaZEHa4ZntkWv/Ck1xqVTXY3T1uZFBLcXMAAZpDqALpYjPZ19DiwCVsBAkZYn0+Pma1+AG55QcERDQGjwn5mF9cek3J47IU= Received: from PU1P153MB0169.APCP153.PROD.OUTLOOK.COM (10.170.189.13) by PU1P153MB0155.APCP153.PROD.OUTLOOK.COM (10.170.189.11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1622.3; Wed, 6 Feb 2019 03:15:25 +0000 Received: from PU1P153MB0169.APCP153.PROD.OUTLOOK.COM ([fe80::7822:a20:e63c:de2f]) by PU1P153MB0169.APCP153.PROD.OUTLOOK.COM ([fe80::7822:a20:e63c:de2f%9]) with mapi id 15.20.1622.006; Wed, 6 Feb 2019 03:15:25 +0000 From: Dexuan Cui To: Dan Williams , "linux-nvdimm@lists.01.org" Subject: [ndctl PATCH 2/2] libndctl: NVDIMM_FAMILY_HYPERV: add .smart_get_shutdown_count (Function 2) Thread-Topic: [ndctl PATCH 2/2] libndctl: NVDIMM_FAMILY_HYPERV: add .smart_get_shutdown_count (Function 2) Thread-Index: AdS9yhDhtmcTHbqXROCIFql5zieMiA== Date: Wed, 6 Feb 2019 03:15:24 +0000 Message-ID: Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: msip_labels: MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_Enabled=True; MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_SiteId=72f988bf-86f1-41af-91ab-2d7cd011db47; MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_Owner=decui@microsoft.com; MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_SetDate=2019-02-06T03:15:23.2837120Z; MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_Name=General; MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_Application=Microsoft Azure Information Protection; MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_ActionId=659dc0ae-4110-4376-b275-196030b7cf90; MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_Extended_MSFT_Method=Automatic x-originating-ip: [2601:600:a280:1760:5896:cf8a:cefe:fd7] x-ms-publictraffictype: Email x-microsoft-exchange-diagnostics: 1; PU1P153MB0155; 6:hapQxyrSHYS+RGJPrKrQk2N0tPbFKUt8zfRaSY1VWfjQ0HfEusKRxypsIol4Vb1oIuql5CyjaUNs5uwhRAQcBswFyK/HPvX8+Tq7/3Zij9hcq61g8njbwba1MTbOCCk33BE5INsXuSQETrkCL1Z7hMFI6+aDfKX6f+UEjP5veqEQDVil04hroEOInYoQ+Xh03xpC4chqrAOzxuJ3rPE03FXh80ZgwvYEusjoKLTm2YSKdaaQnSVRjB5IgQnTcQj/R7H7pITiuaO+JDAYWGbI8BJhMTw5Z6peXaX0MRVZStxYA4xhaD1ogb3kvA+OIFjCiLPWHaLMI3htA4j29LpbbrsvZSGwEq0Gut1z8Ks0sTRPlzLEfD+FvXFmJjyg/4BAHJvaNbgwM2CXzwgYUrSK6PrTEBJpiBxi2fsBRl00wCB+O6nrGzBuAD7dHqudSlafe0IzYqQUQCLbc1RUtHwIYw==; 5:eGBCsDTuiKpxKI6W7EpXusrI6ppyWIY64SdLBVmcQfbSw7Q5GglERcDRI8gr5ZhuOfeQL38cjqBBJilV3VZaeCTMQFqQtcXAopPT9VteeVIFgIBUUC6Iq+LHZeeZmhK258ASrZR2ZdbRE6kzy6NcE5N2nWOX09MuItQZHPaYgUsTfQSmEvV6z2j3oKfZhPgRbTFqC9aDxAXA1AdXlXscGQ==; 7:OOLEDw0kOdFZobWRfiX1vqKPouG0/ltZaHS68zvM70A2JMsJfwR/r6I+f6LgiRu3esSDDJaFtL5ldUa+sZHDi5hHiH1m5Tx2Vams94xn6+JNIRrEDQGWJYNpBcN/XH7+/jWztWAdkrmIKPbSe1b88Q== x-ms-office365-filtering-correlation-id: ed9a1acd-72e0-483b-11b9-08d68be15667 x-ms-office365-filtering-ht: Tenant x-microsoft-antispam: BCL:0; PCL:0; RULEID:(2390118)(7020095)(4652040)(8989299)(5600110)(711020)(4605077)(4618075)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(2017052603328)(7193020); SRVR:PU1P153MB0155; x-ms-traffictypediagnostic: PU1P153MB0155: x-microsoft-antispam-prvs: x-forefront-prvs: 0940A19703 x-forefront-antispam-report: SFV:NSPM; SFS:(10019020)(136003)(396003)(366004)(39860400002)(346002)(376002)(189003)(199004)(53936002)(25786009)(46003)(9686003)(110136005)(476003)(10290500003)(2501003)(22452003)(486006)(55016002)(86362001)(256004)(305945005)(7736002)(7696005)(478600001)(2906002)(99286004)(4326008)(14454004)(68736007)(8990500004)(81156014)(81166006)(86612001)(71200400001)(71190400001)(8936002)(33656002)(102836004)(6506007)(74316002)(6346003)(6436002)(186003)(316002)(97736004)(10090500001)(106356001)(105586002)(6116002)(107886003)(8676002)(142923001); DIR:OUT; SFP:1102; SCL:1; SRVR:PU1P153MB0155; H:PU1P153MB0169.APCP153.PROD.OUTLOOK.COM; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; MX:1; A:1; received-spf: None (protection.outlook.com: microsoft.com does not designate permitted sender hosts) authentication-results: spf=none (sender IP is ) smtp.mailfrom=decui@microsoft.com; x-ms-exchange-senderadcheck: 1 x-microsoft-antispam-message-info: z19SwnCL7y/wNpTJttYOrCjffnwCB14/yu30BQFLX0d7lNXjYyD8yLoljHOF/NuQ0KZT3ezkp7++9s5nEXFpFZ+SGCB19Gv9lQHXcQrJcMJLqwCMeRqdZ6uew8J7CNfXbmgQUECDyWtWtpwg6b5Sa155ezWHDx7kyZbHYb8Mi1sVYNzgdaKvfkwhX94k/sb2yW710fWbNSwxdn5Fk31Quq3Wi+3xTaj2J1ctGT2NxLWKsthC26KxYg/ndX2W+CUebfOwLH/hcZwbKqtYwLiHKOpYTlJ61PAHij1xyOBHFzLFd7PV62FyamdWBJiCrLDDnBnUhGO1BxgWIlfUpAxfeZNg9gcjFS0Ugp2Mlk66OuedXCtK6Bzl2nrouX9CkurPUos+vsdAlQgkY/61i72xlPXjMiJbJvocwSswB5TKUqE= MIME-Version: 1.0 X-OriginatorOrg: microsoft.com X-MS-Exchange-CrossTenant-Network-Message-Id: ed9a1acd-72e0-483b-11b9-08d68be15667 X-MS-Exchange-CrossTenant-originalarrivaltime: 06 Feb 2019 03:15:24.8494 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 72f988bf-86f1-41af-91ab-2d7cd011db47 X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-Transport-CrossTenantHeadersStamped: PU1P153MB0155 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: , Cc: Michael Kelley Errors-To: linux-nvdimm-bounces@lists.01.org Sender: "Linux-nvdimm" X-Virus-Scanned: ClamAV using ClamSMTP With the patch, "ndctl list --dimms --health --idle" can show "shutdown_count" now, e.g. { "dev":"nmem0", "id":"04d5-01-1701-00000000", "handle":0, "phys_id":0, "health":{ "health_state":"ok", "shutdown_count":2 } } The patch has to directly call ndctl_cmd_submit() in hyperv_cmd_smart_get_flags() and hyperv_cmd_smart_get_shutdown_count() to get the needed info, because util_dimm_health_to_json() only submits one command, and unluckily for Hyper-V Virtual NVDIMM we need to call both Function 1 and 2 to get the needed info. My feeling is that it's not good to directly call ndctl_cmd_submit(), but doing this requires no change to the common code, and I'm unsure if it's better to change the common code just for Hyper-V. Signed-off-by: Dexuan Cui --- ndctl/lib/hyperv.c | 62 ++++++++++++++++++++++++++++++++++++++++------ ndctl/lib/hyperv.h | 7 ++++++ 2 files changed, 62 insertions(+), 7 deletions(-) diff --git a/ndctl/lib/hyperv.c b/ndctl/lib/hyperv.c index b303d50..e8ec142 100644 --- a/ndctl/lib/hyperv.c +++ b/ndctl/lib/hyperv.c @@ -22,7 +22,8 @@ #define CMD_HYPERV_STATUS(_c) (CMD_HYPERV(_c)->u.status) #define CMD_HYPERV_SMART_DATA(_c) (CMD_HYPERV(_c)->u.smart.data) -static struct ndctl_cmd *hyperv_dimm_cmd_new_smart(struct ndctl_dimm *dimm) +static struct ndctl_cmd *hyperv_dimm_cmd_new_cmd(struct ndctl_dimm *dimm, + unsigned int command) { struct ndctl_bus *bus = ndctl_dimm_get_bus(dimm); struct ndctl_ctx *ctx = ndctl_bus_get_ctx(bus); @@ -35,8 +36,7 @@ static struct ndctl_cmd *hyperv_dimm_cmd_new_smart(struct ndctl_dimm *dimm) return NULL; } - if (test_dimm_dsm(dimm, ND_HYPERV_CMD_GET_HEALTH_INFO) == - DIMM_DSM_UNSUPPORTED) { + if (test_dimm_dsm(dimm, command) == DIMM_DSM_UNSUPPORTED) { dbg(ctx, "unsupported function\n"); return NULL; } @@ -54,7 +54,7 @@ static struct ndctl_cmd *hyperv_dimm_cmd_new_smart(struct ndctl_dimm *dimm) hyperv = CMD_HYPERV(cmd); hyperv->gen.nd_family = NVDIMM_FAMILY_HYPERV; - hyperv->gen.nd_command = ND_HYPERV_CMD_GET_HEALTH_INFO; + hyperv->gen.nd_command = command; hyperv->gen.nd_fw_size = 0; hyperv->gen.nd_size_in = offsetof(struct nd_hyperv_smart, status); hyperv->gen.nd_size_out = sizeof(hyperv->u.smart); @@ -65,34 +65,74 @@ static struct ndctl_cmd *hyperv_dimm_cmd_new_smart(struct ndctl_dimm *dimm) return cmd; } -static int hyperv_smart_valid(struct ndctl_cmd *cmd) +static struct ndctl_cmd *hyperv_dimm_cmd_new_smart(struct ndctl_dimm *dimm) +{ + return hyperv_dimm_cmd_new_cmd(dimm, ND_HYPERV_CMD_GET_HEALTH_INFO); +} + +static int hyperv_cmd_valid(struct ndctl_cmd *cmd, unsigned int command) { if (cmd->type != ND_CMD_CALL || cmd->size != sizeof(*cmd) + sizeof(struct nd_pkg_hyperv) || CMD_HYPERV(cmd)->gen.nd_family != NVDIMM_FAMILY_HYPERV || - CMD_HYPERV(cmd)->gen.nd_command != ND_HYPERV_CMD_GET_HEALTH_INFO || + CMD_HYPERV(cmd)->gen.nd_command != command || cmd->status != 0 || CMD_HYPERV_STATUS(cmd) != 0) return cmd->status < 0 ? cmd->status : -EINVAL; return 0; } +static int hyperv_smart_valid(struct ndctl_cmd *cmd) +{ + return hyperv_cmd_valid(cmd, ND_HYPERV_CMD_GET_HEALTH_INFO); +} + static int hyperv_cmd_xlat_firmware_status(struct ndctl_cmd *cmd) { return CMD_HYPERV_STATUS(cmd) == 0 ? 0 : -EINVAL; } +static int hyperv_get_shutdown_count(struct ndctl_cmd *cmd, + unsigned int *count) +{ + unsigned int command = ND_HYPERV_CMD_GET_SHUTDOWN_INFO; + struct ndctl_cmd *cmd_get_shutdown_info; + int rc; + + cmd_get_shutdown_info = hyperv_dimm_cmd_new_cmd(cmd->dimm, command); + if (!cmd_get_shutdown_info) + return -EINVAL; + + if (ndctl_cmd_submit(cmd_get_shutdown_info) < 0 || + hyperv_cmd_valid(cmd_get_shutdown_info, command) < 0) { + rc = -EINVAL; + goto out; + } + + *count = CMD_HYPERV(cmd_get_shutdown_info)->u.shutdown_info.count; + rc = 0; +out: + ndctl_cmd_unref(cmd_get_shutdown_info); + return rc; +} + static unsigned int hyperv_cmd_smart_get_flags(struct ndctl_cmd *cmd) { int rc; + unsigned int count; + unsigned int flags = 0; rc = hyperv_smart_valid(cmd); if (rc < 0) { errno = -rc; return 0; } + flags |= ND_SMART_HEALTH_VALID; - return ND_SMART_HEALTH_VALID; + if (hyperv_get_shutdown_count(cmd, &count) == 0) + flags |= ND_SMART_SHUTDOWN_COUNT_VALID; + + return flags; } static unsigned int hyperv_cmd_smart_get_health(struct ndctl_cmd *cmd) @@ -121,9 +161,17 @@ static unsigned int hyperv_cmd_smart_get_health(struct ndctl_cmd *cmd) return health; } +static unsigned int hyperv_cmd_smart_get_shutdown_count(struct ndctl_cmd *cmd) +{ + unsigned int count; + + return hyperv_get_shutdown_count(cmd, &count) == 0 ? count : UINT_MAX; +} + struct ndctl_dimm_ops * const hyperv_dimm_ops = &(struct ndctl_dimm_ops) { .new_smart = hyperv_dimm_cmd_new_smart, .smart_get_flags = hyperv_cmd_smart_get_flags, .smart_get_health = hyperv_cmd_smart_get_health, + .smart_get_shutdown_count = hyperv_cmd_smart_get_shutdown_count, .xlat_firmware_status = hyperv_cmd_xlat_firmware_status, }; diff --git a/ndctl/lib/hyperv.h b/ndctl/lib/hyperv.h index 8e55a97..5232d60 100644 --- a/ndctl/lib/hyperv.h +++ b/ndctl/lib/hyperv.h @@ -19,6 +19,7 @@ enum { /* non-root commands */ ND_HYPERV_CMD_GET_HEALTH_INFO = 1, + ND_HYPERV_CMD_GET_SHUTDOWN_INFO = 2, }; /* @@ -38,9 +39,15 @@ struct nd_hyperv_smart { }; } __attribute__((packed)); +struct nd_hyperv_shutdown_info { + __u32 status; + __u32 count; +} __attribute__((packed)); + union nd_hyperv_cmd { __u32 status; struct nd_hyperv_smart smart; + struct nd_hyperv_shutdown_info shutdown_info; } __attribute__((packed)); struct nd_pkg_hyperv {