From: Sasha Levin <sashal@kernel.org> To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Keith Busch <kbusch@kernel.org>, Sasha Levin <sashal@kernel.org>, Edmund Nadolski <edmund.nadolski@intel.com>, Christoph Hellwig <hch@lst.de>, linux-nvme@lists.infradead.org Subject: [PATCH AUTOSEL 5.3 66/99] nvme: Prevent resets during paused controller state Date: Sat, 26 Oct 2019 09:15:27 -0400 [thread overview] Message-ID: <20191026131600.2507-66-sashal@kernel.org> (raw) In-Reply-To: <20191026131600.2507-1-sashal@kernel.org> From: Keith Busch <kbusch@kernel.org> [ Upstream commit 4c75f877853cfa81b12374a07208e07b077f39b8 ] A paused controller is doing critical internal activation work in the background. Prevent subsequent controller resets from occurring during this period by setting the controller state to RESETTING first. A helper function, nvme_try_sched_reset_work(), is introduced for these paths so they may continue with scheduling the reset_work after they've completed their uninterruptible critical section. Tested-by: Edmund Nadolski <edmund.nadolski@intel.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Keith Busch <kbusch@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org> --- drivers/nvme/host/core.c | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index 7284bee560a0f..b214df2f05850 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -118,6 +118,21 @@ static void nvme_queue_scan(struct nvme_ctrl *ctrl) queue_work(nvme_wq, &ctrl->scan_work); } +/* + * Use this function to proceed with scheduling reset_work for a controller + * that had previously been set to the resetting state. This is intended for + * code paths that can't be interrupted by other reset attempts. A hot removal + * may prevent this from succeeding. + */ +static int nvme_try_sched_reset(struct nvme_ctrl *ctrl) +{ + if (ctrl->state != NVME_CTRL_RESETTING) + return -EBUSY; + if (!queue_work(nvme_reset_wq, &ctrl->reset_work)) + return -EBUSY; + return 0; +} + int nvme_reset_ctrl(struct nvme_ctrl *ctrl) { if (!nvme_change_ctrl_state(ctrl, NVME_CTRL_RESETTING)) @@ -3687,13 +3702,13 @@ static void nvme_fw_act_work(struct work_struct *work) if (time_after(jiffies, fw_act_timeout)) { dev_warn(ctrl->device, "Fw activation timeout, reset controller\n"); - nvme_reset_ctrl(ctrl); - break; + nvme_try_sched_reset(ctrl); + return; } msleep(100); } - if (ctrl->state != NVME_CTRL_LIVE) + if (!nvme_change_ctrl_state(ctrl, NVME_CTRL_LIVE)) return; nvme_start_queues(ctrl); @@ -3713,7 +3728,13 @@ static void nvme_handle_aen_notice(struct nvme_ctrl *ctrl, u32 result) nvme_queue_scan(ctrl); break; case NVME_AER_NOTICE_FW_ACT_STARTING: - queue_work(nvme_wq, &ctrl->fw_act_work); + /* + * We are (ab)using the RESETTING state to prevent subsequent + * recovery actions from interfering with the controller's + * firmware activation. + */ + if (nvme_change_ctrl_state(ctrl, NVME_CTRL_RESETTING)) + queue_work(nvme_wq, &ctrl->fw_act_work); break; #ifdef CONFIG_NVME_MULTIPATH case NVME_AER_NOTICE_ANA: -- 2.20.1 _______________________________________________ Linux-nvme mailing list Linux-nvme@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-nvme
next prev parent reply other threads:[~2019-10-26 13:18 UTC|newest] Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top [not found] <20191026131600.2507-1-sashal@kernel.org> 2019-10-26 13:14 ` [PATCH AUTOSEL 5.3 08/99] nvme: fix possible deadlock when nvme_update_formats fails Sasha Levin 2019-10-26 13:14 ` [PATCH AUTOSEL 5.3 09/99] nvme: retain split access workaround for capability reads Sasha Levin 2019-10-26 13:15 ` [PATCH AUTOSEL 5.3 65/99] nvme-pci: Free tagset if no IO queues Sasha Levin 2019-10-26 13:15 ` Sasha Levin [this message] 2019-10-26 13:15 ` [PATCH AUTOSEL 5.3 74/99] nvmet-loop: fix possible leakage during error flow Sasha Levin 2019-10-26 13:15 ` [PATCH AUTOSEL 5.3 75/99] nvme-tcp: " Sasha Levin
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20191026131600.2507-66-sashal@kernel.org \ --to=sashal@kernel.org \ --cc=edmund.nadolski@intel.com \ --cc=hch@lst.de \ --cc=kbusch@kernel.org \ --cc=linux-kernel@vger.kernel.org \ --cc=linux-nvme@lists.infradead.org \ --cc=stable@vger.kernel.org \ --subject='Re: [PATCH AUTOSEL 5.3 66/99] nvme: Prevent resets during paused controller state' \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).