Skip to contentSkip to conversation

nvme/quirk: backport to v4.4 stable for PCI_DEVICE(0x1c58, 0x0003)

PATCH New Mauricio Faria de Oliveira 4 participants 7 messages Jun 21, 2017 – Jun 27, 2017

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

cover nvme/quirk: backport to v4.4 stable for PCI_DEVICE(0x1c58, 0x0003)

Hi Christoph, Jens, and Greg.

Would you ack these 2 backports to be applied to v4.4 stable?

The backports differ from the upstream applied commits in two aspects:
1) use PCI IDs directly rather than nvme quirk infrastructure (which was introduced later, commit 106198edb7 "nvme: add explicit quirk handling", and depends on many further changes, not required for this purpose).

2) use 'struct nvme_dev->tagset' rather than 'struct nvme_ctrl->tagset' (similarly.)

This has been built and tested on top of v4.4.70.

Thanks,

Mauricio Faria de Oliveira
IBM Linux Technology Center

Guilherme G. Piccoli (2):
nvme/quirk: Add a delay before checking for adapter readiness
nvme: apply DELAY_BEFORE_CHK_RDY quirk at probe time too

 drivers/nvme/host/nvme.h | 7 +++++++
 drivers/nvme/host/pci.c  | 5 +++++
 2 files changed, 12 insertions(+)
Signature · 1 line
1.8.3.1
#1 lore raw

PATCH 1/2 nvme/quirk: Add a delay before checking for adapter readiness

From: "Guilherme G. Piccoli" <[email protected]>

When disabling the controller, the specification says the register NVME_REG_CC should be written and then driver needs to wait the adapter to be ready, which is checked by reading another register bit (NVME_CSTS_RDY). There's a timeout validation in this checking, so in case this timeout is reached the driver gives up and removes the adapter from the system.

After a firmware activation procedure, the PCI_DEVICE(0x1c58, 0x0003) (HGST adapter) end up being removed if we issue a reset_controller, because driver keeps verifying the NVME_REG_CSTS until the timeout is reached. This patch adds a necessary quirk for this adapter, by introducing a delay before nvme_wait_ready(), so the reset procedure is able to be completed. This quirk is needed because just increasing the timeout is not enough in case of this adapter - the driver must wait before start reading NVME_REG_CSTS register on this specific device.

Signed-off-by Guilherme G. Piccoli <gpiccoli at linux.vnet.ibm.com>
Reviewed-by Christoph Hellwig <hch at lst.de>
Signed-off-by Jens Axboe <axboe at fb.com>
[mauricfo: backport to v4.4.70 without nvme quirk handling & nvme_ctrl]
Signed-off-by Mauricio Faria de Oliveira <mauricfo at linux.vnet.ibm.com>
Tested-by Narasimhan Vaidyanathan <vnarasimhan at in.ibm.com>
---
 drivers/nvme/host/nvme.h |  7 +++++++
 drivers/nvme/host/pci.c  | 10 ++++++++++
 2 files changed, 17 insertions(+)
drivers/nvme/host/nvme.h +7 -0
index 044253dca30a..b8a5a8e8f57d 100644
@@ -27,6 +27,13 @@ enum {
 	NVME_NS_LIGHTNVM	= 1,
 };
 
+/* The below value is the specific amount of delay needed before checking
+ * readiness in case of the PCI_DEVICE(0x1c58, 0x0003), which needs the
+ * NVME_QUIRK_DELAY_BEFORE_CHK_RDY quirk enabled. The value (in ms) was
+ * found empirically.
+ */
+#define NVME_QUIRK_DELAY_AMOUNT		2000
+
 /*
  * Represents an NVM Express device.  Each nvme_dev is a PCI function.
  */
drivers/nvme/host/pci.c +10 -0
index c851bc53831c..e9750a0a6f2c 100644
@@ -1633,10 +1633,20 @@ static int nvme_wait_ready(struct nvme_dev *dev, u64 cap, bool enabled)
  */
 static int nvme_disable_ctrl(struct nvme_dev *dev, u64 cap)
 {
+	struct pci_dev *pdev = to_pci_dev(dev->dev);
+
 	dev->ctrl_config &= ~NVME_CC_SHN_MASK;
 	dev->ctrl_config &= ~NVME_CC_ENABLE;
 	writel(dev->ctrl_config, &dev->bar->cc);
 
+	/* Checking for dev->tagset is a trick to avoid sleeping on module
+	 * load, since we only need the quirk on reset_controller. Notice
+	 * that the HGST device needs this delay only in firmware activation
+	 * procedure; unfortunately we have no (easy) way to verify this.
+	 */
+	if (pdev->vendor == 0x1c58 && pdev->device == 0x0003 && dev->tagset)
+		msleep(NVME_QUIRK_DELAY_AMOUNT);
+
 	return nvme_wait_ready(dev, cap, false);
 }
 
Signature · 1 line
1.8.3.1
#2 lore raw

PATCH 2/2 nvme: apply DELAY_BEFORE_CHK_RDY quirk at probe time too

In reply to Mauricio Faria de Oliveira

From: "Guilherme G. Piccoli" <[email protected]>

Commit 54adc01055b7 ("nvme/quirk: Add a delay before checking for adapter readiness") introduced a quirk to adapters that cannot read the bit NVME_CSTS_RDY right after register NVME_REG_CC is set; these adapters need a delay or else the action of reading the bit NVME_CSTS_RDY could somehow corrupt adapter's registers state and it never recovers.

When this quirk was added, we checked ctrl->tagset in order to avoid quirking in probe time, supposing we would never require such delay during probe. Well, it was too optimistic; we in fact need this quirk at probe time in some cases, like after a kexec.

In some experiments, after abnormal shutdown of machine (aka power cord unplug), we booted into our bootloader in Power, which is a Linux kernel, and kexec'ed into another distro. If this kexec is too quick, we end up reaching the probe of NVMe adapter in that distro when adapter is in bad state (not fully initialized on our bootloader). What happens next is that nvme_wait_ready() is unable to complete, except if the quirk is enabled.

So, this patch removes the original ctrl->tagset verification in order to enable the quirk even on probe time.

Fixes 54adc01055b7 ("nvme/quirk: Add a delay before checking for adapter readiness")
Reported-by Andrew Byrne <byrneadw at ie.ibm.com>
Reported-by Jaime A. H. Gomez <jahgomez at mx1.ibm.com>
Reported-by Zachary D. Myers <zdmyers at us.ibm.com>
Signed-off-by Guilherme G. Piccoli <gpiccoli at linux.vnet.ibm.com>
Acked-by Jeffrey Lien <Jeff.Lien at wdc.com>
Signed-off-by Christoph Hellwig <hch at lst.de>
[mauricfo: backport to v4.4.70 without nvme quirk handling & nvme_ctrl]
Signed-off-by Mauricio Faria de Oliveira <mauricfo at linux.vnet.ibm.com>
Tested-by Narasimhan Vaidyanathan <vnarasimhan at in.ibm.com>
---
 drivers/nvme/host/pci.c | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)
drivers/nvme/host/pci.c +1 -6
index e9750a0a6f2c..4c673d45f1bd 100644
@@ -1639,12 +1639,7 @@ static int nvme_disable_ctrl(struct nvme_dev *dev, u64 cap)
 	dev->ctrl_config &= ~NVME_CC_ENABLE;
 	writel(dev->ctrl_config, &dev->bar->cc);
 
-	/* Checking for dev->tagset is a trick to avoid sleeping on module
-	 * load, since we only need the quirk on reset_controller. Notice
-	 * that the HGST device needs this delay only in firmware activation
-	 * procedure; unfortunately we have no (easy) way to verify this.
-	 */
-	if (pdev->vendor == 0x1c58 && pdev->device == 0x0003 && dev->tagset)
+	if (pdev->vendor == 0x1c58 && pdev->device == 0x0003)
 		msleep(NVME_QUIRK_DELAY_AMOUNT);
 
 	return nvme_wait_ready(dev, cap, false);
Signature · 1 line
1.8.3.1
maintainer
#3 lore raw

cover nvme/quirk: backport to v4.4 stable for PCI_DEVICE(0x1c58, 0x0003)

In reply to Mauricio Faria de Oliveira
Quoted 9 lines · Mauricio Faria de Oliveira

Hi Christoph, Jens, and Greg.

Would you ack these 2 backports to be applied to v4.4 stable?

The backports differ from the upstream applied commits in two aspects:
1) use PCI IDs directly rather than nvme quirk infrastructure (which was introduced later, commit 106198edb7 "nvme: add explicit quirk handling", and depends on many further changes, not required for this purpose).

Quoted 4 lines

2) use 'struct nvme_dev->tagset' rather than 'struct nvme_ctrl->tagset' (similarly.)

This has been built and tested on top of v4.4.70.

Applying those two to stable is fine with me.

Signature · 1 line
Jens Axboe
#4 lore raw

cover nvme/quirk: backport to v4.4 stable for PCI_DEVICE(0x1c58, 0x0003)

Quoted 10 lines · Jens Axboe
Quoted 9 lines · Mauricio Faria de Oliveira

Hi Christoph, Jens, and Greg.

Would you ack these 2 backports to be applied to v4.4 stable?

The backports differ from the upstream applied commits in two aspects:
1) use PCI IDs directly rather than nvme quirk infrastructure (which was introduced later, commit 106198edb7 "nvme: add explicit quirk handling", and depends on many further changes, not required for this purpose).

Quoted 7 lines
Quoted 4 lines

2) use 'struct nvme_dev->tagset' rather than 'struct nvme_ctrl->tagset' (similarly.)

This has been built and tested on top of v4.4.70.

Applying those two to stable is fine with me.

Thanks Maur?cio for the great backport (which I tested and it's working properly, as expected).

And thanks Jens for the quick ack.
Cheers,

Guilherme

#5 lore raw

cover nvme/quirk: backport to v4.4 stable for PCI_DEVICE(0x1c58, 0x0003)

In reply to Mauricio Faria de Oliveira
Quoted 9 lines · Mauricio Faria de Oliveira

Hi Christoph, Jens, and Greg.

Would you ack these 2 backports to be applied to v4.4 stable?

The backports differ from the upstream applied commits in two aspects:
1) use PCI IDs directly rather than nvme quirk infrastructure (which was introduced later, commit 106198edb7 "nvme: add explicit quirk handling", and depends on many further changes, not required for this purpose).

Quoted 4 lines

2) use 'struct nvme_dev->tagset' rather than 'struct nvme_ctrl->tagset' (similarly.)

This has been built and tested on top of v4.4.70.

Always tell me what the git commit ids are for the patches in Linus's tree, as I need them. I dug it out this time...

thanks,

greg k-h

#6 lore raw

cover nvme/quirk: backport to v4.4 stable for PCI_DEVICE(0x1c58, 0x0003)

Quoted 13 lines · Greg KH
Quoted 12 lines · Mauricio Faria de Oliveira

Hi Christoph, Jens, and Greg.

Would you ack these 2 backports to be applied to v4.4 stable?

The backports differ from the upstream applied commits in two aspects:
1) use PCI IDs directly rather than nvme quirk infrastructure (which was introduced later, commit 106198edb7 "nvme: add explicit quirk handling", and depends on many further changes, not required for this purpose).

2) use 'struct nvme_dev->tagset' rather than 'struct nvme_ctrl->tagset' (similarly.)

Quoted 9 lines
Quoted 1 line

This has been built and tested on top of v4.4.70.

Always tell me what the git commit ids are for the patches in Linus's tree, as I need them. I dug it out this time...

thanks,

greg k-h

Thanks a lot Greg! Next time we won't forget.
Cheers,

Guilherme