All of lore.kernel.org
 help / color / mirror / Atom feed
From: gjoyce@linux.ibm.com
To: linux-nvme@lists.infradead.org
Cc: kbusch@kernel.org, axboe@fb.com, hch@lst.de, sagi@grimberg.me,
	hare@suse.de, dwagner@suse.de, msuchanek@suse.de,
	jonathan.derrick@linux.dev, okozina@redhat.com,
	nilay@linux.ibm.com, gjoyce@linux.ibm.com
Subject: [PATCH 1/1] nvme: retry security commands if media not ready
Date: Mon, 30 Sep 2024 11:48:43 -0500	[thread overview]
Message-ID: <20240930164845.8406-2-gjoyce@linux.ibm.com> (raw)
In-Reply-To: <20240930164845.8406-1-gjoyce@linux.ibm.com>

From: Greg Joyce <gjoyce@linux.ibm.com>

If NVME_CC_CRIME is set, security send/receive commands may fail
with status NVME_SC_ADMIN_COMMAND_MEDIA_NOT_READY until the
controller is able to accepts these commands. Retry the command
if this failure occurs.

Signed-off-by: Greg Joyce <gjoyce@linux.ibm.com>
---
 drivers/nvme/host/core.c | 82 ++++++++++++++++++++++++++--------------
 1 file changed, 54 insertions(+), 28 deletions(-)

diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index ba6508455e18..fc4bbf1adf9f 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -2320,12 +2320,53 @@ static int nvme_get_unique_id(struct gendisk *disk, u8 id[16],
 	return nvme_ns_get_unique_id(disk->private_data, id, type);
 }
 
+static u32 nvme_get_timeout(struct nvme_ctrl *ctrl)
+{
+	u32 timeout;
+	int ret;
+
+	timeout = NVME_CAP_TIMEOUT(ctrl->cap);
+	if (ctrl->cap & NVME_CAP_CRMS_CRWMS) {
+		u32 crto, ready_timeout;
+
+		ret = ctrl->ops->reg_read32(ctrl, NVME_REG_CRTO, &crto);
+		if (ret) {
+			dev_err(ctrl->device, "Reading CRTO failed (%d)\n",
+				ret);
+			return ret;
+		}
+
+		/*
+		 * CRTO should always be greater or equal to CAP.TO, but some
+		 * devices are known to get this wrong. Use the larger of the
+		 * two values.
+		 */
+		if (ctrl->ctrl_config & NVME_CC_CRIME)
+			ready_timeout = NVME_CRTO_CRIMT(crto);
+		else
+			ready_timeout = NVME_CRTO_CRWMT(crto);
+
+		if (ready_timeout < timeout) {
+			dev_warn_once(ctrl->device, "bad crto:%x cap:%llx\n",
+				      crto, ctrl->cap);
+		} else
+			timeout = ready_timeout;
+	}
+	return timeout;
+}
+
 #ifdef CONFIG_BLK_SED_OPAL
 static int nvme_sec_submit(void *data, u16 spsp, u8 secp, void *buffer, size_t len,
 		bool send)
 {
 	struct nvme_ctrl *ctrl = data;
 	struct nvme_command cmd = { };
+	u32 timeout;
+	unsigned long timeout_jiffies;
+	int ret;
+
+	timeout = nvme_get_timeout(ctrl);
+	timeout_jiffies = jiffies + timeout * HZ;
 
 	if (send)
 		cmd.common.opcode = nvme_admin_security_send;
@@ -2335,8 +2376,19 @@ static int nvme_sec_submit(void *data, u16 spsp, u8 secp, void *buffer, size_t l
 	cmd.common.cdw10 = cpu_to_le32(((u32)secp) << 24 | ((u32)spsp) << 8);
 	cmd.common.cdw11 = cpu_to_le32(len);
 
-	return __nvme_submit_sync_cmd(ctrl->admin_q, &cmd, NULL, buffer, len,
+	ret = __nvme_submit_sync_cmd(ctrl->admin_q, &cmd, NULL, buffer, len,
 			NVME_QID_ANY, NVME_SUBMIT_AT_HEAD);
+	while (ret == NVME_SC_ADMIN_COMMAND_MEDIA_NOT_READY) {
+		if (time_after(jiffies, timeout_jiffies)) {
+			dev_err(ctrl->device,
+				"Device media not ready; aborting\n");
+			return -ENODEV;
+		}
+		ssleep(1);
+		ret =  __nvme_submit_sync_cmd(ctrl->admin_q, &cmd, NULL, buffer,
+				len, NVME_QID_ANY, NVME_SUBMIT_AT_HEAD);
+	}
+	return ret;
 }
 
 static void nvme_configure_opal(struct nvme_ctrl *ctrl, bool was_suspended)
@@ -2473,33 +2525,7 @@ int nvme_enable_ctrl(struct nvme_ctrl *ctrl)
 	if (ret)
 		return ret;
 
-	timeout = NVME_CAP_TIMEOUT(ctrl->cap);
-	if (ctrl->cap & NVME_CAP_CRMS_CRWMS) {
-		u32 crto, ready_timeout;
-
-		ret = ctrl->ops->reg_read32(ctrl, NVME_REG_CRTO, &crto);
-		if (ret) {
-			dev_err(ctrl->device, "Reading CRTO failed (%d)\n",
-				ret);
-			return ret;
-		}
-
-		/*
-		 * CRTO should always be greater or equal to CAP.TO, but some
-		 * devices are known to get this wrong. Use the larger of the
-		 * two values.
-		 */
-		if (ctrl->ctrl_config & NVME_CC_CRIME)
-			ready_timeout = NVME_CRTO_CRIMT(crto);
-		else
-			ready_timeout = NVME_CRTO_CRWMT(crto);
-
-		if (ready_timeout < timeout)
-			dev_warn_once(ctrl->device, "bad crto:%x cap:%llx\n",
-				      crto, ctrl->cap);
-		else
-			timeout = ready_timeout;
-	}
+	timeout = nvme_get_timeout(ctrl);
 
 	ctrl->ctrl_config |= NVME_CC_ENABLE;
 	ret = ctrl->ops->reg_write32(ctrl, NVME_REG_CC, ctrl->ctrl_config);
-- 
gjoyce@linux.ibm.com



  reply	other threads:[~2024-09-30 16:49 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-09-30 16:48 [PATCH 0/1] nvme: add retry for media not ready error gjoyce
2024-09-30 16:48 ` gjoyce [this message]
2024-10-02  8:16   ` [PATCH 1/1] nvme: retry security commands if media not ready Christoph Hellwig
2024-10-02 16:51     ` Greg Joyce
2024-10-03 12:43       ` Christoph Hellwig
2024-10-03 13:30         ` Greg Joyce
2024-10-03 14:41           ` Christoph Hellwig
2024-10-03 23:35             ` Greg Joyce
2024-10-04  5:41               ` Christoph Hellwig
2024-10-04  7:22                 ` Nilay Shroff
2024-10-04 12:24                   ` Christoph Hellwig

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=20240930164845.8406-2-gjoyce@linux.ibm.com \
    --to=gjoyce@linux.ibm.com \
    --cc=axboe@fb.com \
    --cc=dwagner@suse.de \
    --cc=hare@suse.de \
    --cc=hch@lst.de \
    --cc=jonathan.derrick@linux.dev \
    --cc=kbusch@kernel.org \
    --cc=linux-nvme@lists.infradead.org \
    --cc=msuchanek@suse.de \
    --cc=nilay@linux.ibm.com \
    --cc=okozina@redhat.com \
    --cc=sagi@grimberg.me \
    /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
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.