Received: by 2002:a25:1506:0:0:0:0:0 with SMTP id 6csp1073708ybv; Thu, 20 Feb 2020 12:39:18 -0800 (PST) X-Google-Smtp-Source: APXvYqwjCTS/gPsvD4stQ2eFE+iwdkZECSWp0Xj11egFNKwHu50c2BX7MBlPXIbNzRoyp1gjjd6k X-Received: by 2002:a9d:638a:: with SMTP id w10mr12484185otk.130.1582231158136; Thu, 20 Feb 2020 12:39:18 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1582231158; cv=none; d=google.com; s=arc-20160816; b=HLyAA/jPQdzfI87ZH3Swns/YwIqhI90y+VVoWu0tw4K4KzbDYPvbAUHuYRKdd2Ews9 MNX+4zQ0XV0s1wQnk0C+7BNIwNOv8Ve7YTv/Z9UFD7kZquSAAIPN+7lZxmii4mxt26QQ /GJfDMePISqyS7FOJqHkC2/vf4IxdLxggx6nLlUGi/INiM906LAD4hHJDSgsPoZuLSf2 VkfGza9aJb9s4+oA4/gmx+YBxVgAW5lc4acMzRuCDZIEkdVPDQvlcLNGQbYBm/tMN0Te FnzFkefRjkNu3dhpjicqR7mV+BhQpf55EUIvietCaxQTIWBZjZEl2cbkJzI5M+H33Ebq G0/g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:subject:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:cc:to:from; bh=1uUgw68sq4RHUCnWSc3CFfyl77imUTGyMSDrs6TZ63Y=; b=SIfKdDetvlf3wLFOjHxB1LOiryUQceb9AR3gjJoK6HDwqr5O8tMEcvaG9N6Mm568mR S92Qnay9KuEwEhsDCYAF0DVXBihhPedasFcziGeyQlA+wQd2l9F5jeRkoYqO1O7bCxiO xhAP72adJnnxvrHdqLPr5D8ZOkmkSFVzmvDg43q7tQjtm0kXt8hI+X7nVLKlaY7reVfV qgS4OVtPWr7P3jEN0dEq4+Z5zvGCL6gZP78a8oaAVISoWV4RsXrwcpnZPxk+K8DtdzSQ t1Rtd93Uan6KYm4DL2Pnd5D1NWwhSHkJy2086ipwGHyuRFbtck7UtAMA7GrmhCdRZv+V YR8A== ARC-Authentication-Results: i=1; mx.google.com; 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 Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id u25si176861oic.160.2020.02.20.12.39.05; Thu, 20 Feb 2020 12:39:18 -0800 (PST) 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; 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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729213AbgBTUhd (ORCPT + 99 others); Thu, 20 Feb 2020 15:37:33 -0500 Received: from ale.deltatee.com ([207.54.116.67]:45126 "EHLO ale.deltatee.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728582AbgBTUhB (ORCPT ); Thu, 20 Feb 2020 15:37:01 -0500 Received: from cgy1-donard.priv.deltatee.com ([172.16.1.31]) by ale.deltatee.com with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1j4sZ8-0005cd-KG; Thu, 20 Feb 2020 13:37:00 -0700 Received: from gunthorp by cgy1-donard.priv.deltatee.com with local (Exim 4.92) (envelope-from ) id 1j4sZ8-0006yS-Ee; Thu, 20 Feb 2020 13:36:58 -0700 From: Logan Gunthorpe To: linux-kernel@vger.kernel.org, linux-nvme@lists.infradead.org Cc: Christoph Hellwig , Sagi Grimberg , Keith Busch , Jens Axboe , Chaitanya Kulkarni , Max Gurtovoy , Stephen Bates , Logan Gunthorpe , Chaitanya Kulkarni Date: Thu, 20 Feb 2020 13:36:51 -0700 Message-Id: <20200220203652.26734-9-logang@deltatee.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200220203652.26734-1-logang@deltatee.com> References: <20200220203652.26734-1-logang@deltatee.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SA-Exim-Connect-IP: 172.16.1.31 X-SA-Exim-Rcpt-To: linux-kernel@vger.kernel.org, linux-nvme@lists.infradead.org, hch@lst.de, sagi@grimberg.me, kbusch@kernel.org, axboe@fb.com, maxg@mellanox.com, sbates@raithlin.com, logang@deltatee.com, Chaitanya.Kulkarni@wdc.com, chaitanya.kulkarni@wdc.com X-SA-Exim-Mail-From: gunthorp@deltatee.com X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on ale.deltatee.com X-Spam-Level: X-Spam-Status: No, score=-6.5 required=5.0 tests=ALL_TRUSTED,BAYES_00, MYRULES_FREE,MYRULES_NO_TEXT,URIBL_BLOCKED autolearn=no autolearn_force=no version=3.4.2 Subject: [PATCH v11 8/9] nvmet-passthru: Add enable/disable helpers X-SA-Exim-Version: 4.2.1 (built Wed, 08 May 2019 21:11:16 +0000) X-SA-Exim-Scanned: Yes (on ale.deltatee.com) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This patch adds helper functions which are used in the NVMeOF configfs when the user is configuring the passthru subsystem. Here we ensure that only one subsys is assigned to each nvme_ctrl by using an xarray on the cntlid. The subsystem's version number is overridden by the passed through controller's version. However, if that version is less than 1.2.1, then we bump the advertised version to that and print a warning in dmesg. Based-on-a-patch-by: Chaitanya Kulkarni Signed-off-by: Logan Gunthorpe --- drivers/nvme/target/configfs.c | 3 ++ drivers/nvme/target/core.c | 10 +++- drivers/nvme/target/nvmet.h | 12 +++++ drivers/nvme/target/passthru.c | 87 ++++++++++++++++++++++++++++++++++ 4 files changed, 111 insertions(+), 1 deletion(-) diff --git a/drivers/nvme/target/configfs.c b/drivers/nvme/target/configfs.c index 98613a45bd3b..354d43fab8db 100644 --- a/drivers/nvme/target/configfs.c +++ b/drivers/nvme/target/configfs.c @@ -828,6 +828,9 @@ static ssize_t nvmet_subsys_attr_version_store(struct config_item *item, int major, minor, tertiary = 0; int ret; + /* passthru subsystems use the underlying controller's version */ + if (nvmet_passthru_ctrl(subsys)) + return -EINVAL; ret = sscanf(page, "%d.%d.%d\n", &major, &minor, &tertiary); if (ret != 2 && ret != 3) diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c index 40998b514439..b282fb4e45ed 100644 --- a/drivers/nvme/target/core.c +++ b/drivers/nvme/target/core.c @@ -522,6 +522,12 @@ int nvmet_ns_enable(struct nvmet_ns *ns) mutex_lock(&subsys->lock); ret = 0; + + if (nvmet_passthru_ctrl(subsys)) { + pr_info("cannot enable both passthru and regular namespaces for a single subsystem"); + goto out_unlock; + } + if (ns->enabled) goto out_unlock; @@ -1418,7 +1424,7 @@ struct nvmet_subsys *nvmet_subsys_alloc(const char *subsysnqn, if (!subsys) return ERR_PTR(-ENOMEM); - subsys->ver = NVME_VS(1, 3, 0); /* NVMe 1.3.0 */ + subsys->ver = NVMET_DEFAULT_VS; /* generate a random serial number as our controllers are ephemeral: */ get_random_bytes(&subsys->serial, sizeof(subsys->serial)); @@ -1459,6 +1465,8 @@ static void nvmet_subsys_free(struct kref *ref) WARN_ON_ONCE(!list_empty(&subsys->namespaces)); + nvmet_passthru_subsys_free(subsys); + kfree(subsys->subsysnqn); kfree(subsys); } diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h index 6e632d0a88ca..7c247d803015 100644 --- a/drivers/nvme/target/nvmet.h +++ b/drivers/nvme/target/nvmet.h @@ -20,6 +20,8 @@ #include #include +#define NVMET_DEFAULT_VS NVME_VS(1, 3, 0) + #define NVMET_ASYNC_EVENTS 4 #define NVMET_ERROR_LOG_SLOTS 128 #define NVMET_NO_ERROR_LOC ((u16)-1) @@ -230,6 +232,7 @@ struct nvmet_subsys { #ifdef CONFIG_NVME_TARGET_PASSTHRU struct nvme_ctrl *passthru_ctrl; + char *passthru_ctrl_path; #endif /* CONFIG_NVME_TARGET_PASSTHRU */ }; @@ -512,6 +515,9 @@ static inline u32 nvmet_dsm_len(struct nvmet_req *req) } #ifdef CONFIG_NVME_TARGET_PASSTHRU +void nvmet_passthru_subsys_free(struct nvmet_subsys *subsys); +int nvmet_passthru_ctrl_enable(struct nvmet_subsys *subsys); +void nvmet_passthru_ctrl_disable(struct nvmet_subsys *subsys); u16 nvmet_parse_passthru_admin_cmd(struct nvmet_req *req); u16 nvmet_setup_passthru_command(struct nvmet_req *req); static inline struct nvme_ctrl *nvmet_passthru_ctrl(struct nvmet_subsys *subsys) @@ -519,6 +525,12 @@ static inline struct nvme_ctrl *nvmet_passthru_ctrl(struct nvmet_subsys *subsys) return subsys->passthru_ctrl; } #else /* CONFIG_NVME_TARGET_PASSTHRU */ +static inline void nvmet_passthru_subsys_free(struct nvmet_subsys *subsys) +{ +} +static inline void nvmet_passthru_ctrl_disable(struct nvmet_subsys *subsys) +{ +} static inline u16 nvmet_parse_passthru_admin_cmd(struct nvmet_req *req) { return 0; diff --git a/drivers/nvme/target/passthru.c b/drivers/nvme/target/passthru.c index 01127bfa6c8a..0705f4ff8b16 100644 --- a/drivers/nvme/target/passthru.c +++ b/drivers/nvme/target/passthru.c @@ -11,6 +11,11 @@ #include "../host/nvme.h" #include "nvmet.h" +/* + * xarray to maintain one passthru subsystem per nvme controller. + */ +static DEFINE_XARRAY(passthru_subsystems); + static void nvmet_passthru_execute_cmd_work(struct work_struct *w) { struct nvmet_req *req = container_of(w, struct nvmet_req, p.work); @@ -346,3 +351,85 @@ u16 nvmet_parse_passthru_admin_cmd(struct nvmet_req *req) return NVME_SC_INVALID_OPCODE | NVME_SC_DNR; } } + +int nvmet_passthru_ctrl_enable(struct nvmet_subsys *subsys) +{ + struct nvme_ctrl *ctrl; + int ret = -EINVAL; + void *old; + + mutex_lock(&subsys->lock); + if (!subsys->passthru_ctrl_path) + goto out_unlock; + if (subsys->passthru_ctrl) + goto out_unlock; + + if (subsys->nr_namespaces) { + pr_info("cannot enable both passthru and regular namespaces for a single subsystem"); + goto out_unlock; + } + + ctrl = nvme_ctrl_get_by_path(subsys->passthru_ctrl_path); + if (IS_ERR(ctrl)) { + ret = PTR_ERR(ctrl); + pr_err("failed to open nvme controller %s\n", + subsys->passthru_ctrl_path); + + goto out_unlock; + } + + old = xa_cmpxchg(&passthru_subsystems, ctrl->cntlid, NULL, + subsys, GFP_KERNEL); + if (xa_is_err(old)) { + ret = xa_err(old); + goto out_put_ctrl; + } + + if (old) + goto out_put_ctrl; + + subsys->passthru_ctrl = ctrl; + subsys->ver = ctrl->vs; + + if (subsys->ver < NVME_VS(1, 2, 1)) { + pr_warn("nvme controller version is too old: %d.%d.%d, advertising 1.2.1\n", + (int)NVME_MAJOR(subsys->ver), + (int)NVME_MINOR(subsys->ver), + (int)NVME_TERTIARY(subsys->ver)); + subsys->ver = NVME_VS(1, 2, 1); + } + + mutex_unlock(&subsys->lock); + return 0; + +out_put_ctrl: + nvme_put_ctrl(ctrl); +out_unlock: + mutex_unlock(&subsys->lock); + return ret; +} + +static void __nvmet_passthru_ctrl_disable(struct nvmet_subsys *subsys) +{ + if (subsys->passthru_ctrl) { + xa_erase(&passthru_subsystems, subsys->passthru_ctrl->cntlid); + nvme_put_ctrl(subsys->passthru_ctrl); + } + subsys->passthru_ctrl = NULL; + subsys->ver = NVMET_DEFAULT_VS; +} + +void nvmet_passthru_ctrl_disable(struct nvmet_subsys *subsys) +{ + mutex_lock(&subsys->lock); + __nvmet_passthru_ctrl_disable(subsys); + mutex_unlock(&subsys->lock); +} + +void nvmet_passthru_subsys_free(struct nvmet_subsys *subsys) +{ + mutex_lock(&subsys->lock); + __nvmet_passthru_ctrl_disable(subsys); + kfree(subsys->passthru_ctrl_path); + mutex_unlock(&subsys->lock); +} -- 2.20.1