Received: by 2002:a25:5b86:0:0:0:0:0 with SMTP id p128csp1346570ybb; Fri, 29 Mar 2019 02:40:53 -0700 (PDT) X-Google-Smtp-Source: APXvYqw9RzzRAElGBMuMfvs1vyhtqJrynqxIF1I2atEdHXLaTn4GAv1u+detrxI4wZxLwTUj9sG1 X-Received: by 2002:aa7:938b:: with SMTP id t11mr38858749pfe.67.1553852453470; Fri, 29 Mar 2019 02:40:53 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1553852453; cv=none; d=google.com; s=arc-20160816; b=V1ynx7bXBW9lTIR6SkyegMCVYAtOSYICjImZB4+WDxsQA+7BVnGotLF6ckOigH8ip6 t6o+/XwaEEk46jOrz89UtUp2x//hYDPAlV18xA7fBYWjx4OVztDEU7+otpFJiwEIZYON jkex/KLeqBCvp9u7QSa7pNd6jdQt+ei71d3yx5PyT79zdmvo1U99CVPQcyYhv4yYsU4E 2+CkuScC4qBgtY41oaruvkb9u2Qkz/sYjK0f5FQf1VGuea509rScXplx8Tkyz/vbnQPL bcV/YWcksEk3WQEX7ltzHBMkzv0k4cdb+Fut//NIA4+r8w7ZdVcIQT0ZUvFj97IQzWHt qjUg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:to:mime-version:references:in-reply-to :message-id:date:subject:cc:from:dkim-signature; bh=fXLVY5+2nhXhJKp1ggMduny1m+DljsbrpPUJj33lapM=; b=YpJdF+RvVNTtol83CLEMlNPBM38jTvFk9cr4kKWYT6O4uP2Vdaxk8s3reDXTdIlU1d V89gempkUG3nyA8zCgpwDqMw+fj3h8pEZ8Fd6DjHzkQhe42GTfpDZuxRvgsllFoCdVH4 L23DvScLUCugQvyOtYXLfhPgjNnaPuDvX45G4WzGx66Z5uBw1rF0iwAzy6YAo6fyktgi tpnt9Q/14lfUtODcPwh8GIHet0PU9DYPKHZcb7XJ4/V1f/352r8+3jnkM8a7jnROFv+q 4G8nvNw1AV6pzvTgNZb+Bo06jPcpwVYRL4LImxeWcOdSJ3NPgTPPL3AMrN0G3RXZg5Oc xhmg== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@amazon.de header.s=amazon201209 header.b=qgPkTK+t; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=amazon.de Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id m1si1483520plt.28.2019.03.29.02.40.38; Fri, 29 Mar 2019 02:40:53 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=fail header.i=@amazon.de header.s=amazon201209 header.b=qgPkTK+t; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=amazon.de Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728846AbfC2Jju (ORCPT + 99 others); Fri, 29 Mar 2019 05:39:50 -0400 Received: from smtp-fw-6001.amazon.com ([52.95.48.154]:10549 "EHLO smtp-fw-6001.amazon.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727387AbfC2Jjt (ORCPT ); Fri, 29 Mar 2019 05:39:49 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amazon.de; i=@amazon.de; q=dns/txt; s=amazon201209; t=1553852388; x=1585388388; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version; bh=fXLVY5+2nhXhJKp1ggMduny1m+DljsbrpPUJj33lapM=; b=qgPkTK+tl1QAFQdzJztCMGMiSFZO08QXBz0q9YLwD4RqBx+VQjrTHIwo +geW9WWlUsNDB0NUzJlVDsbKHyfwHcvUl8FmUP+R7JN9wNkaAemG6nISW aIjA/pjy5KosYFxsoGge4VfkIfqOpBhGj1VCe/AxTD3lCopA9gQ6E1oq8 g=; X-IronPort-AV: E=Sophos;i="5.60,284,1549929600"; d="scan'208";a="388115262" Received: from iad6-co-svc-p1-lb1-vlan3.amazon.com (HELO email-inbound-relay-1e-57e1d233.us-east-1.amazon.com) ([10.124.125.6]) by smtp-border-fw-out-6001.iad6.amazon.com with ESMTP/TLS/DHE-RSA-AES256-SHA; 29 Mar 2019 09:39:45 +0000 Received: from EX13MTAUEA001.ant.amazon.com (iad55-ws-svc-p15-lb9-vlan2.iad.amazon.com [10.40.159.162]) by email-inbound-relay-1e-57e1d233.us-east-1.amazon.com (8.14.7/8.14.7) with ESMTP id x2T9dfG1095115 (version=TLSv1/SSLv3 cipher=AES256-SHA bits=256 verify=FAIL); Fri, 29 Mar 2019 09:39:43 GMT Received: from EX13D18EUC001.ant.amazon.com (10.43.164.108) by EX13MTAUEA001.ant.amazon.com (10.43.61.82) with Microsoft SMTP Server (TLS) id 15.0.1367.3; Fri, 29 Mar 2019 09:39:41 +0000 Received: from EX13MTAUWA001.ant.amazon.com (10.43.160.58) by EX13D18EUC001.ant.amazon.com (10.43.164.108) with Microsoft SMTP Server (TLS) id 15.0.1367.3; Fri, 29 Mar 2019 09:39:40 +0000 Received: from dev-dsk-mheyne-60001.pdx1.corp.amazon.com (10.184.85.242) by mail-relay.amazon.com (10.43.160.118) with Microsoft SMTP Server id 15.0.1367.3 via Frontend Transport; Fri, 29 Mar 2019 09:39:39 +0000 Received: by dev-dsk-mheyne-60001.pdx1.corp.amazon.com (Postfix, from userid 5466572) id 3185D247D4; Fri, 29 Mar 2019 09:39:39 +0000 (UTC) From: Maximilian Heyne CC: David Woodhouse , Amit Shah , Maximilian Heyne , Keith Busch , Jens Axboe , Christoph Hellwig , Sagi Grimberg , , Subject: [PATCH 2/2] nvme: add sysfs controls for io and admin timeouts Date: Fri, 29 Mar 2019 09:39:21 +0000 Message-ID: <20190329093921.95710-2-mheyne@amazon.de> X-Mailer: git-send-email 2.16.5 In-Reply-To: <20190329093921.95710-1-mheyne@amazon.de> References: <20190329093921.95710-1-mheyne@amazon.de> MIME-Version: 1.0 Content-Type: text/plain To: unlisted-recipients:; (no To-header on input) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Add two sysfs files for reading and updating the admin and io timeouts of individual NVMe devices. For this, two new nvme_ctrl_ops were added to update the respective timeouts. This patch implements these ops for the pci nvme driver. Therefore, only the timeouts for PCI NVMe devices can be updated. Original-patch-by: Milan Pandurov Signed-off-by: Maximilian Heyne --- drivers/nvme/host/core.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++ drivers/nvme/host/nvme.h | 2 ++ drivers/nvme/host/pci.c | 28 ++++++++++++++++++ 3 files changed, 104 insertions(+) diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index d0530bf7a677..f77201c508fa 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -2768,6 +2768,74 @@ static ssize_t nvme_sysfs_rescan(struct device *dev, } static DEVICE_ATTR(rescan_controller, S_IWUSR, NULL, nvme_sysfs_rescan); +static ssize_t io_timeout_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct nvme_ctrl *ctrl = dev_get_drvdata(dev); + + return scnprintf(buf, PAGE_SIZE, "%u\n", ctrl->io_timeout/HZ); +} + +static ssize_t io_timeout_store(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t count) +{ + struct nvme_ctrl *ctrl = dev_get_drvdata(dev); + unsigned int timeout; + int ret; + + ret = kstrtouint(buf, 10u, &timeout); + if (ret == -EINVAL) { + dev_warn(ctrl->dev, "Error parsing timeout value.\n"); + return ret; + } + if (ret == -ERANGE || timeout == 0 || timeout > UINT_MAX/HZ) { + dev_warn(ctrl->dev, + "Timeout value out of range (0 < timeout <= %u).\n", + UINT_MAX/HZ); + return -ERANGE; + } + ret = ctrl->ops->set_io_timeout(ctrl, timeout * HZ); + if (ret < 0) + return ret; + return count; +} +static DEVICE_ATTR_RW(io_timeout); + +static ssize_t admin_timeout_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct nvme_ctrl *ctrl = dev_get_drvdata(dev); + + return scnprintf(buf, PAGE_SIZE, "%u\n", ctrl->admin_timeout/HZ); +} + +static ssize_t admin_timeout_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct nvme_ctrl *ctrl = dev_get_drvdata(dev); + unsigned int timeout; + int ret; + + ret = kstrtouint(buf, 10u, &timeout); + if (ret == -EINVAL) { + dev_warn(ctrl->dev, "Error parsing timeout value.\n"); + return ret; + } + if (ret == -ERANGE || timeout == 0 || timeout > UINT_MAX/HZ) { + dev_warn(ctrl->dev, + "Timeout value out of range (0 < timeout <= %u).\n", + UINT_MAX/HZ); + return -ERANGE; + } + ret = ctrl->ops->set_admin_timeout(ctrl, timeout * HZ); + if (ret < 0) + return ret; + return count; +} +static DEVICE_ATTR_RW(admin_timeout); + static inline struct nvme_ns_head *dev_to_ns_head(struct device *dev) { struct gendisk *disk = dev_to_disk(dev); @@ -3008,6 +3076,8 @@ static struct attribute *nvme_dev_attrs[] = { &dev_attr_address.attr, &dev_attr_state.attr, &dev_attr_numa_node.attr, + &dev_attr_io_timeout.attr, + &dev_attr_admin_timeout.attr, NULL }; @@ -3021,6 +3091,10 @@ static umode_t nvme_dev_attrs_are_visible(struct kobject *kobj, return 0; if (a == &dev_attr_address.attr && !ctrl->ops->get_address) return 0; + if (a == &dev_attr_io_timeout.attr && !ctrl->ops->set_io_timeout) + return 0; + if (a == &dev_attr_admin_timeout.attr && !ctrl->ops->set_admin_timeout) + return 0; return a->mode; } diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h index 1397650edfda..4dc13c5990bd 100644 --- a/drivers/nvme/host/nvme.h +++ b/drivers/nvme/host/nvme.h @@ -367,6 +367,8 @@ struct nvme_ctrl_ops { int (*reg_read32)(struct nvme_ctrl *ctrl, u32 off, u32 *val); int (*reg_write32)(struct nvme_ctrl *ctrl, u32 off, u32 val); int (*reg_read64)(struct nvme_ctrl *ctrl, u32 off, u64 *val); + int (*set_io_timeout)(struct nvme_ctrl *ctrl, unsigned int timeout); + int (*set_admin_timeout)(struct nvme_ctrl *ctrl, unsigned int timeout); void (*free_ctrl)(struct nvme_ctrl *ctrl); void (*submit_async_event)(struct nvme_ctrl *ctrl); void (*delete_ctrl)(struct nvme_ctrl *ctrl); diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index 16d7a00fecf0..6932895c3519 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c @@ -2647,6 +2647,32 @@ static int nvme_pci_get_address(struct nvme_ctrl *ctrl, char *buf, int size) return snprintf(buf, size, "%s", dev_name(&pdev->dev)); } +static int nvme_pci_set_io_timeout(struct nvme_ctrl *ctrl, unsigned int timeout) +{ + struct nvme_dev *dev = to_nvme_dev(ctrl); + struct nvme_ns *ns; + + ctrl->io_timeout = timeout; + dev->tagset.timeout = timeout; + down_write(&ctrl->namespaces_rwsem); + list_for_each_entry(ns, &ctrl->namespaces, list) { + blk_queue_rq_timeout(ns->queue, timeout); + } + up_write(&ctrl->namespaces_rwsem); + return 0; +} + +static int nvme_pci_set_admin_timeout(struct nvme_ctrl *ctrl, + unsigned int timeout) +{ + struct nvme_dev *dev = to_nvme_dev(ctrl); + + ctrl->admin_timeout = timeout; + dev->admin_tagset.timeout = timeout; + blk_queue_rq_timeout(ctrl->admin_q, timeout); + return 0; +} + static const struct nvme_ctrl_ops nvme_pci_ctrl_ops = { .name = "pcie", .module = THIS_MODULE, @@ -2655,6 +2681,8 @@ static const struct nvme_ctrl_ops nvme_pci_ctrl_ops = { .reg_read32 = nvme_pci_reg_read32, .reg_write32 = nvme_pci_reg_write32, .reg_read64 = nvme_pci_reg_read64, + .set_io_timeout = nvme_pci_set_io_timeout, + .set_admin_timeout = nvme_pci_set_admin_timeout, .free_ctrl = nvme_pci_free_ctrl, .submit_async_event = nvme_pci_submit_async_event, .get_address = nvme_pci_get_address, -- 2.16.5 Amazon Development Center Germany GmbH Krausenstr. 38 10117 Berlin Geschaeftsfuehrer: Christian Schlaeger, Ralf Herbrich Ust-ID: DE 289 237 879 Eingetragen am Amtsgericht Charlottenburg HRB 149173 B