linux-hyperv.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] PCI: pci-hyperv: Retry PCI bus D0 entry when the first attempt failed with invalid device state 0xC0000184.
@ 2020-04-26 13:24 Wei Hu
  2020-04-27  0:15 ` Michael Kelley
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Wei Hu @ 2020-04-26 13:24 UTC (permalink / raw)
  To: kys, haiyangz, sthemmin, wei.liu, lorenzo.pieralisi, robh,
	bhelgaas, linux-hyperv, linux-pci, linux-kernel, decui, mikelley
  Cc: Wei Hu

In the case of kdump, the PCI device was not cleanly shut down
before the kdump kernel starts. This causes the initial
attempt of entering D0 state in the kdump kernel to fail with
invalid device state 0xC0000184 returned from Hyper-V host.
When this happens, explicitly call PCI bus exit and retry to
enter the D0 state.

Also fix the PCI probe failure path to release the PCI device
resource properly.

Signed-off-by: Wei Hu <weh@microsoft.com>
---
 drivers/pci/controller/pci-hyperv.c | 34 ++++++++++++++++++++++++++++-
 1 file changed, 33 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c
index e15022ff63e3..eb4781fa058d 100644
--- a/drivers/pci/controller/pci-hyperv.c
+++ b/drivers/pci/controller/pci-hyperv.c
@@ -2736,6 +2736,10 @@ static void hv_free_config_window(struct hv_pcibus_device *hbus)
 	vmbus_free_mmio(hbus->mem_config->start, PCI_CONFIG_MMIO_LENGTH);
 }
 
+#define STATUS_INVALID_DEVICE_STATE		0xC0000184
+
+static int hv_pci_bus_exit(struct hv_device *hdev, bool hibernating);
+
 /**
  * hv_pci_enter_d0() - Bring the "bus" into the D0 power state
  * @hdev:	VMBus's tracking struct for this root PCI bus
@@ -2748,8 +2752,10 @@ static int hv_pci_enter_d0(struct hv_device *hdev)
 	struct pci_bus_d0_entry *d0_entry;
 	struct hv_pci_compl comp_pkt;
 	struct pci_packet *pkt;
+	bool retry = true;
 	int ret;
 
+enter_d0_retry:
 	/*
 	 * Tell the host that the bus is ready to use, and moved into the
 	 * powered-on state.  This includes telling the host which region
@@ -2780,6 +2786,30 @@ static int hv_pci_enter_d0(struct hv_device *hdev)
 		dev_err(&hdev->device,
 			"PCI Pass-through VSP failed D0 Entry with status %x\n",
 			comp_pkt.completion_status);
+
+		/*
+		 * In certain case (Kdump) the pci device of interest was
+		 * not cleanly shut down and resource is still held on host
+		 * side, the host could return STATUS_INVALID_DEVICE_STATE.
+		 * We need to explicitly request host to release the resource
+		 * and try to enter D0 again.
+		 */
+		if (comp_pkt.completion_status == STATUS_INVALID_DEVICE_STATE &&
+		    retry) {
+			ret = hv_pci_bus_exit(hdev, true);
+
+			retry = false;
+
+			if (ret == 0) {
+				kfree(pkt);
+				goto enter_d0_retry;
+			} else {
+				dev_err(&hdev->device,
+					"PCI bus D0 exit failed with ret %d\n",
+					ret);
+			}
+		}
+
 		ret = -EPROTO;
 		goto exit;
 	}
@@ -3136,7 +3166,7 @@ static int hv_pci_probe(struct hv_device *hdev,
 
 	ret = hv_pci_allocate_bridge_windows(hbus);
 	if (ret)
-		goto free_irq_domain;
+		goto exit_d0;
 
 	ret = hv_send_resources_allocated(hdev);
 	if (ret)
@@ -3154,6 +3184,8 @@ static int hv_pci_probe(struct hv_device *hdev,
 
 free_windows:
 	hv_pci_free_bridge_windows(hbus);
+exit_d0:
+	(void) hv_pci_bus_exit(hdev, true);
 free_irq_domain:
 	irq_domain_remove(hbus->irq_domain);
 free_fwnode:
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread
* RE: [PATCH] PCI: pci-hyperv: Retry PCI bus D0 entry when the first attempt failed with invalid device state 0xC0000184.
@ 2020-04-27  1:30 Dexuan Cui
  0 siblings, 0 replies; 9+ messages in thread
From: Dexuan Cui @ 2020-04-27  1:30 UTC (permalink / raw)
  To: Wei Hu, KY Srinivasan, Haiyang Zhang, Stephen Hemminger,
	wei.liu@kernel.org, lorenzo.pieralisi@arm.com, robh@kernel.org,
	bhelgaas@google.com, linux-hyperv@vger.kernel.org,
	linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org,
	Michael Kelley

> From: Wei Hu <weh@microsoft.com>
> Sent: Sunday, April 26, 2020 6:25 AM
> Subject: [PATCH] PCI: pci-hyperv: Retry PCI bus D0 entry when the first attempt
> failed with invalid device state 0xC0000184.

The title looks too long. :-)
Ideally it should be shorter than 75 chars. I suggest the part 
"with invalid device state 0xC0000184. " should be removed.

> +#define STATUS_INVALID_DEVICE_STATE		0xC0000184
> +
> +static int hv_pci_bus_exit(struct hv_device *hdev, bool hibernating);

Should we change the name of the parameter 'hibernating'?

>  /**
>   * hv_pci_enter_d0() - Bring the "bus" into the D0 power state
>   * @hdev:	VMBus's tracking struct for this root PCI bus
> @@ -2748,8 +2752,10 @@ static int hv_pci_enter_d0(struct hv_device *hdev)
>  	struct pci_bus_d0_entry *d0_entry;
>  	struct hv_pci_compl comp_pkt;
>  	struct pci_packet *pkt;
> +	bool retry = true;
>  	int ret;
> 
> +enter_d0_retry:
>  	/*
>  	 * Tell the host that the bus is ready to use, and moved into the
>  	 * powered-on state.  This includes telling the host which region
> @@ -2780,6 +2786,30 @@ static int hv_pci_enter_d0(struct hv_device *hdev)
>  		dev_err(&hdev->device,
>  			"PCI Pass-through VSP failed D0 Entry with status %x\n",
>  			comp_pkt.completion_status);
> +
> +		/*
> +		 * In certain case (Kdump) the pci device of interest was
> +		 * not cleanly shut down and resource is still held on host
> +		 * side, the host could return STATUS_INVALID_DEVICE_STATE.
> +		 * We need to explicitly request host to release the resource
> +		 * and try to enter D0 again.
> +		 */
> +		if (comp_pkt.completion_status == STATUS_INVALID_DEVICE_STATE
> &&
> +		    retry) {

Maybe it's better to just retry for any error in comp_pkt.completion_status?
Just in case the host returns a slightly different error code in future.

Thanks,
-- Dexuan

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2020-04-29 23:47 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-04-26 13:24 [PATCH] PCI: pci-hyperv: Retry PCI bus D0 entry when the first attempt failed with invalid device state 0xC0000184 Wei Hu
2020-04-27  0:15 ` Michael Kelley
2020-04-27  7:05   ` Wei Hu
2020-04-27 15:36     ` Michael Kelley
2020-04-28  6:41       ` Wei Hu
2020-04-29 23:47         ` Michael Kelley
2020-04-27 10:21 ` Wei Liu
2020-04-27 22:51 ` Bjorn Helgaas
  -- strict thread matches above, loose matches on Subject: below --
2020-04-27  1:30 Dexuan Cui

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).