Received: by 2002:a05:6a10:206:0:0:0:0 with SMTP id 6csp3550186pxj; Mon, 24 May 2021 09:10:03 -0700 (PDT) X-Google-Smtp-Source: ABdhPJx7l9hQ3RsFd44Hz8/OwTqOEYpBZZb/GHgqZo7cxlrqdjeHx1XN3YwDs8J+FSgUeaOymtsq X-Received: by 2002:a02:5142:: with SMTP id s63mr24867407jaa.82.1621872603493; Mon, 24 May 2021 09:10:03 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1621872603; cv=none; d=google.com; s=arc-20160816; b=ta1J58iicfxRqbbUwEkRSmMNp1j5zI9GdziRObFGLhJzClegcWBa7Bcy61jEcxT7Gy 21kY+9Qa6oAMmpuzGYO7hsZYdlrRAPcasM808JnvFXLJOhEGf+1WpzOSuLnAXEN7YEB7 ngyV/N7W6xiSltmV8paHd/YR/RjqNMWmyS7nJersD9SHuwM/qwh/m0A8PjxBCGX191cB LYdI9ht6aZbLy61jpd7Wk3ygsRXowMH2hgl05o+yxxcbXEipdqezlBJO45fbgWbM9ZpS mRtou2DvhXCmuIWGKJgwhwV0e2vKZqoXqdb6hPO8BiNGmQis3UyB03ss/QX89mZVz42E Mo0Q== 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=7FD/unnFOIYtIENgqEWcJv1/DjrCZA7ZriJPzT7Rql4=; b=YUwmtlyXQQWhXRxSud+iISIamx0NzTjBxPy3bSFNJYfzqqtqcxg/SCP86kZ1mwEGUJ rlKA311nfw7vWorC96yAINgBASSSR+spthf3PKwvwxfESgVDlQzi1y8hWrVHh5bmHNPB poiQw0LXZs8HlajrjT9ImOKNB3nd8M5A6bqFM3WWaC52i20tXBglXwzRueevkongHWkN 8YMHl08tc3QuzYo34EtOjcFoEFqgablwm9PM4Z8XJ3XsfoPmbaGjmpMnyTD8eJxw/j+R Kw7pWJF+YwFk/N/gYt6SOci/57C+85TU6Ds1bJyM5g6QhYQMe88UY9upNgk5r+VAILym Iscw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=H8XEj3me; 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 d4si15116496iow.13.2021.05.24.09.09.49; Mon, 24 May 2021 09:10:03 -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=H8XEj3me; 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 S238194AbhEXQJy (ORCPT + 99 others); Mon, 24 May 2021 12:09:54 -0400 Received: from mail.kernel.org ([198.145.29.99]:48388 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235114AbhEXQBV (ORCPT ); Mon, 24 May 2021 12:01:21 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id E335E6199D; Mon, 24 May 2021 15:46:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1621871213; bh=0RDdkCaJj6/IcUKHMH65D/oFfPHyie12c+wiDxaTcWA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=H8XEj3meM74m8Sc1J7va5Ya7jghx+xcv5kTz/EiRmZaXvyjQ6jYsl+HRW8hZSB42Z HGOPdZE8RXM7nkrRit9Sl9z93b9U9wEXDYeryotBtgw6LK68MVcYCIqmYA7Nj++9CR uilkshDsG91C4SmF2k5liT+6KD2TtYOTDmQ4/hO8= 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.12 125/127] nvme-multipath: fix double initialization of ANA state Date: Mon, 24 May 2021 17:27:22 +0200 Message-Id: <20210524152339.094749326@linuxfoundation.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210524152334.857620285@linuxfoundation.org> References: <20210524152334.857620285@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 @@ -3190,7 +3190,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) @@ -4580,6 +4580,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 @@ -709,9 +709,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 || @@ -723,37 +732,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 @@ -668,7 +668,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); @@ -742,7 +743,10 @@ static inline void nvme_mpath_check_last static inline void nvme_trace_bio_complete(struct request *req) { } -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))