Received: by 2002:a05:6a10:206:0:0:0:0 with SMTP id 6csp3543123pxj; Mon, 24 May 2021 09:02:30 -0700 (PDT) X-Google-Smtp-Source: ABdhPJw8rf3PNOa+b48JgXQQi6O5zZjQpyFL9nldTpnhEe+ojcusQ7mieFHK1bNNn6W196kmn9oS X-Received: by 2002:a92:b00d:: with SMTP id x13mr19713334ilh.181.1621872150489; Mon, 24 May 2021 09:02:30 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1621872150; cv=none; d=google.com; s=arc-20160816; b=wk6Zub6ot67hF19t+eapiI6Nbp4mzcUWmfRmPtO1LM3FfJHOkBPBkGc6sD3c4zTfSb 8eOmWiWkinx4sa+4CZlHMq3kOTXS0loaFgw+MqvKZQSdy1/S98uGYzKbmHAXXuaK0RyU xU7iiEEgfGJdZnKjkn7JNAXQ5ewDkidyC7vXoWLWxcJccu/aKVdEsWs8YB8aty3C+FFA op+rAX/4DFOHk3zm0gqi83JcKrkYUrfaF13TrGLINpvly7rfuVk0ts2ASHONg44bi3S5 MWhZrhyd3j5h3NeuZ56yyvXGUxCjTI5OBGpOwTGj4U00owPvW9lzJFOFuhxhaeFfeMRY P5FA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=Qzuh8yS5Q149K5mJhs3xPBm3vVCC2mcY/oyi26v7f8U=; b=gqmBM/cR7/YaAPP6Qc5nhPhqOHa2nI8YjUqjWPMqZA3k67+frLuTSHO0Y57NGwnURi LOquflicC+DWD1bDdokJDbKZHB7a/2YQPR/NcG/P9ysAcNKXbqLlOPocjW5LNgkObrVz qBdtnBWTTfajfxcvVzvt2tR4LJfOIn7QmBrgbFCClKPVjm/Gx4ZXoM395QhBR5f55JH/ Mdyg9HEZZIgG0iQxa++JeMvhaIrygWmbVN1ORL3lFh6vQXlTJQG9BR9kGM6T2+cc3tT6 7cD4PMGNCRvsx1nROdpQlaGdnTxN6EZgPyoNpKpDlI72wOdeseNB/ITv15NwAaW8fihj X8cQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=eXIF+xNL; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id a16si13647001ilr.160.2021.05.24.09.02.14; Mon, 24 May 2021 09:02:30 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=eXIF+xNL; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235741AbhEXQCZ (ORCPT + 99 others); Mon, 24 May 2021 12:02:25 -0400 Received: from mail.kernel.org ([198.145.29.99]:39954 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235113AbhEXPzq (ORCPT ); Mon, 24 May 2021 11:55:46 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 1CEDC6193E; Mon, 24 May 2021 15:42:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1621870933; bh=gM6Rgk/SivELehT/98LaDrKID/I6xh+Ygu/AMIgc5AI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=eXIF+xNLZsqKROWdEkUkHUXg5m+PJ/ok1AVMNtwjIYU8f4qwEcCwK23ouHmuvZ3Qt VM9Jzyqq/5Al61VB7iTawUoce0D+DQITaTdHQF7t1Q2EdEZEz8pimOVIvCyr92b5uS nsLrcBuQ6NKNTIk2MVg7aehGfRtAtTGUuNHvt0ew= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Martin Wilck , Christoph Hellwig , Keith Busch , Sagi Grimberg , Hannes Reinecke Subject: [PATCH 5.10 102/104] nvme-multipath: fix double initialization of ANA state Date: Mon, 24 May 2021 17:26:37 +0200 Message-Id: <20210524152336.237654277@linuxfoundation.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210524152332.844251980@linuxfoundation.org> References: <20210524152332.844251980@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Christoph Hellwig commit 5e1f689913a4498e3081093670ef9d85b2c60920 upstream. nvme_init_identify and thus nvme_mpath_init can be called multiple times and thus must not overwrite potentially initialized or in-use fields. Split out a helper for the basic initialization when the controller is initialized and make sure the init_identify path does not blindly change in-use data structures. Fixes: 0d0b660f214d ("nvme: add ANA support") Reported-by: Martin Wilck Signed-off-by: Christoph Hellwig Reviewed-by: Keith Busch Reviewed-by: Sagi Grimberg Reviewed-by: Hannes Reinecke Signed-off-by: Greg Kroah-Hartman --- drivers/nvme/host/core.c | 3 +- drivers/nvme/host/multipath.c | 55 ++++++++++++++++++++++-------------------- drivers/nvme/host/nvme.h | 8 ++++-- 3 files changed, 37 insertions(+), 29 deletions(-) --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -3131,7 +3131,7 @@ int nvme_init_identify(struct nvme_ctrl ctrl->hmmaxd = le16_to_cpu(id->hmmaxd); } - ret = nvme_mpath_init(ctrl, id); + ret = nvme_mpath_init_identify(ctrl, id); kfree(id); if (ret < 0) @@ -4517,6 +4517,7 @@ int nvme_init_ctrl(struct nvme_ctrl *ctr min(default_ps_max_latency_us, (unsigned long)S32_MAX)); nvme_fault_inject_init(&ctrl->fault_inject, dev_name(ctrl->device)); + nvme_mpath_init_ctrl(ctrl); return 0; out_free_name: --- a/drivers/nvme/host/multipath.c +++ b/drivers/nvme/host/multipath.c @@ -708,9 +708,18 @@ void nvme_mpath_remove_disk(struct nvme_ put_disk(head->disk); } -int nvme_mpath_init(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id) +void nvme_mpath_init_ctrl(struct nvme_ctrl *ctrl) { - int error; + mutex_init(&ctrl->ana_lock); + timer_setup(&ctrl->anatt_timer, nvme_anatt_timeout, 0); + INIT_WORK(&ctrl->ana_work, nvme_ana_work); +} + +int nvme_mpath_init_identify(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id) +{ + size_t max_transfer_size = ctrl->max_hw_sectors << SECTOR_SHIFT; + size_t ana_log_size; + int error = 0; /* check if multipath is enabled and we have the capability */ if (!multipath || !ctrl->subsys || @@ -722,37 +731,31 @@ int nvme_mpath_init(struct nvme_ctrl *ct ctrl->nanagrpid = le32_to_cpu(id->nanagrpid); ctrl->anagrpmax = le32_to_cpu(id->anagrpmax); - mutex_init(&ctrl->ana_lock); - timer_setup(&ctrl->anatt_timer, nvme_anatt_timeout, 0); - ctrl->ana_log_size = sizeof(struct nvme_ana_rsp_hdr) + - ctrl->nanagrpid * sizeof(struct nvme_ana_group_desc); - ctrl->ana_log_size += ctrl->max_namespaces * sizeof(__le32); - - if (ctrl->ana_log_size > ctrl->max_hw_sectors << SECTOR_SHIFT) { + ana_log_size = sizeof(struct nvme_ana_rsp_hdr) + + ctrl->nanagrpid * sizeof(struct nvme_ana_group_desc) + + ctrl->max_namespaces * sizeof(__le32); + if (ana_log_size > max_transfer_size) { dev_err(ctrl->device, - "ANA log page size (%zd) larger than MDTS (%d).\n", - ctrl->ana_log_size, - ctrl->max_hw_sectors << SECTOR_SHIFT); + "ANA log page size (%zd) larger than MDTS (%zd).\n", + ana_log_size, max_transfer_size); dev_err(ctrl->device, "disabling ANA support.\n"); - return 0; + goto out_uninit; } - - INIT_WORK(&ctrl->ana_work, nvme_ana_work); - kfree(ctrl->ana_log_buf); - ctrl->ana_log_buf = kmalloc(ctrl->ana_log_size, GFP_KERNEL); - if (!ctrl->ana_log_buf) { - error = -ENOMEM; - goto out; + if (ana_log_size > ctrl->ana_log_size) { + nvme_mpath_stop(ctrl); + kfree(ctrl->ana_log_buf); + ctrl->ana_log_buf = kmalloc(ctrl->ana_log_size, GFP_KERNEL); + if (!ctrl->ana_log_buf) + return -ENOMEM; } - + ctrl->ana_log_size = ana_log_size; error = nvme_read_ana_log(ctrl); if (error) - goto out_free_ana_log_buf; + goto out_uninit; return 0; -out_free_ana_log_buf: - kfree(ctrl->ana_log_buf); - ctrl->ana_log_buf = NULL; -out: + +out_uninit: + nvme_mpath_uninit(ctrl); return error; } --- a/drivers/nvme/host/nvme.h +++ b/drivers/nvme/host/nvme.h @@ -654,7 +654,8 @@ void nvme_kick_requeue_lists(struct nvme int nvme_mpath_alloc_disk(struct nvme_ctrl *ctrl,struct nvme_ns_head *head); void nvme_mpath_add_disk(struct nvme_ns *ns, struct nvme_id_ns *id); void nvme_mpath_remove_disk(struct nvme_ns_head *head); -int nvme_mpath_init(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id); +int nvme_mpath_init_identify(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id); +void nvme_mpath_init_ctrl(struct nvme_ctrl *ctrl); void nvme_mpath_uninit(struct nvme_ctrl *ctrl); void nvme_mpath_stop(struct nvme_ctrl *ctrl); bool nvme_mpath_clear_current_path(struct nvme_ns *ns); @@ -730,7 +731,10 @@ static inline void nvme_trace_bio_comple blk_status_t status) { } -static inline int nvme_mpath_init(struct nvme_ctrl *ctrl, +static inline void nvme_mpath_init_ctrl(struct nvme_ctrl *ctrl) +{ +} +static inline int nvme_mpath_init_identify(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id) { if (ctrl->subsys->cmic & (1 << 3))