diff mbox series

[3/6] pcie: add power indicator blink check

Message ID 20211011120504.254053-4-kraxel@redhat.com (mailing list archive)
State New, archived
Headers show
Series RfC: try improve native hotplug for pcie root ports | expand

Commit Message

Gerd Hoffmann Oct. 11, 2021, 12:05 p.m. UTC
Refuse to push the attention button in case the guest is busy with some
hotplug operation (as indicated by the power indicator blinking).

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/pci/pcie.c | 7 +++++++
 1 file changed, 7 insertions(+)

Comments

Michael S. Tsirkin Nov. 15, 2021, 11:29 a.m. UTC | #1
On Mon, Oct 11, 2021 at 02:05:01PM +0200, Gerd Hoffmann wrote:
> Refuse to push the attention button in case the guest is busy with some
> hotplug operation (as indicated by the power indicator blinking).
> 
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>

Can't we do better and press the button later after
indicator stops blinking?

> ---
>  hw/pci/pcie.c | 7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
> index 4a52c250615e..c455f92e16bf 100644
> --- a/hw/pci/pcie.c
> +++ b/hw/pci/pcie.c
> @@ -506,6 +506,7 @@ void pcie_cap_slot_unplug_request_cb(HotplugHandler *hotplug_dev,
>      PCIDevice *hotplug_pdev = PCI_DEVICE(hotplug_dev);
>      uint8_t *exp_cap = hotplug_pdev->config + hotplug_pdev->exp.exp_cap;
>      uint32_t sltcap = pci_get_word(exp_cap + PCI_EXP_SLTCAP);
> +    uint16_t sltctl = pci_get_word(exp_cap + PCI_EXP_SLTCTL);
>  
>      /* Check if hot-unplug is disabled on the slot */
>      if ((sltcap & PCI_EXP_SLTCAP_HPC) == 0) {
> @@ -521,6 +522,12 @@ void pcie_cap_slot_unplug_request_cb(HotplugHandler *hotplug_dev,
>          return;
>      }
>  
> +    if ((sltctl & PCI_EXP_SLTCTL_PIC) == PCI_EXP_SLTCTL_PWR_IND_BLINK) {
> +        error_setg(errp, "Hot-unplug failed: "
> +                   "guest is busy (power indicator blinking)");
> +        return;
> +    }
> +
>      dev->pending_deleted_event = true;
>  
>      /* In case user cancel the operation of multi-function hot-add,
> -- 
> 2.31.1
Gerd Hoffmann Nov. 15, 2021, 2:52 p.m. UTC | #2
On Mon, Nov 15, 2021 at 06:29:18AM -0500, Michael S. Tsirkin wrote:
> On Mon, Oct 11, 2021 at 02:05:01PM +0200, Gerd Hoffmann wrote:
> > Refuse to push the attention button in case the guest is busy with some
> > hotplug operation (as indicated by the power indicator blinking).
> > 
> > Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> 
> Can't we do better and press the button later after
> indicator stops blinking?

I don't think this is a good idea.  acpi hotplug doesn't do automatic
retries either, and IMHO the behavior of acpi and native hotplug should
be as close as possible so management apps do not need to handle these
cases differently.

Specifically OpenStack will continue re-trying device_del commands
(mentioned by Daniel a few weeks ago) as long as it doesn't receive
the completion event, so things should work just fine as-is.

Beside that the typical workflow would be that the guest completes
device shutdown, then turns off power (-> qemu unplugs device and
sends completion event now), then turns off the power indicator led.
So in most cases the reason to press the button is gone when the
indicator stops blinking ...

take care,
  Gerd
diff mbox series

Patch

diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
index 4a52c250615e..c455f92e16bf 100644
--- a/hw/pci/pcie.c
+++ b/hw/pci/pcie.c
@@ -506,6 +506,7 @@  void pcie_cap_slot_unplug_request_cb(HotplugHandler *hotplug_dev,
     PCIDevice *hotplug_pdev = PCI_DEVICE(hotplug_dev);
     uint8_t *exp_cap = hotplug_pdev->config + hotplug_pdev->exp.exp_cap;
     uint32_t sltcap = pci_get_word(exp_cap + PCI_EXP_SLTCAP);
+    uint16_t sltctl = pci_get_word(exp_cap + PCI_EXP_SLTCTL);
 
     /* Check if hot-unplug is disabled on the slot */
     if ((sltcap & PCI_EXP_SLTCAP_HPC) == 0) {
@@ -521,6 +522,12 @@  void pcie_cap_slot_unplug_request_cb(HotplugHandler *hotplug_dev,
         return;
     }
 
+    if ((sltctl & PCI_EXP_SLTCTL_PIC) == PCI_EXP_SLTCTL_PWR_IND_BLINK) {
+        error_setg(errp, "Hot-unplug failed: "
+                   "guest is busy (power indicator blinking)");
+        return;
+    }
+
     dev->pending_deleted_event = true;
 
     /* In case user cancel the operation of multi-function hot-add,