On Mon, 15 Nov 2021 11:39:09 -0500
"Michael S. Tsirkin" <mst@redhat.com> wrote:
> From: Gerd Hoffmann <kraxel@redhat.com>
>
> Add an expire time for pending delete, once the time is over allow
> pressing the attention button again.
>
> This makes pcie hotplug behave more like acpi hotplug, where one can
> try sending an 'device_del' monitor command again in case the guest
> didn't respond to the first attempt.
>
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> Message-Id: <20211111130859.1171890-7-kraxel@redhat.com>
> Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
> ---
> include/hw/qdev-core.h | 1 +
> hw/pci/pcie.c | 2 ++
> softmmu/qdev-monitor.c | 4 +++-
> 3 files changed, 6 insertions(+), 1 deletion(-)
>
> diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
> index 72622bd337..20d3066595 100644
> --- a/include/hw/qdev-core.h
> +++ b/include/hw/qdev-core.h
> @@ -181,6 +181,7 @@ struct DeviceState {
> char *canonical_path;
> bool realized;
> bool pending_deleted_event;
> + int64_t pending_deleted_expires_ms;
> QDict *opts;
> int hotplugged;
> bool allow_unplug_during_migration;
> diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
> index a930ac738a..c5ed266337 100644
> --- a/hw/pci/pcie.c
> +++ b/hw/pci/pcie.c
> @@ -548,6 +548,8 @@ void pcie_cap_slot_unplug_request_cb(HotplugHandler *hotplug_dev,
> }
>
> dev->pending_deleted_event = true;
> + dev->pending_deleted_expires_ms =
> + qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + 5000; /* 5 secs */
do we block migration if unplug was requested?
(if not we might loose this state on destionatio, do we care about it?)
>
> /* In case user cancel the operation of multi-function hot-add,
> * remove the function that is unexposed to guest individually,
> diff --git a/softmmu/qdev-monitor.c b/softmmu/qdev-monitor.c
> index 588a62b88d..5925f1ae5f 100644
> --- a/softmmu/qdev-monitor.c
> +++ b/softmmu/qdev-monitor.c
> @@ -943,7 +943,9 @@ void qmp_device_del(const char *id, Error **errp)
> {
> DeviceState *dev = find_device_state(id, errp);
> if (dev != NULL) {
> - if (dev->pending_deleted_event) {
> + if (dev->pending_deleted_event &&
> + (dev->pending_deleted_expires_ms == 0 ||
> + dev->pending_deleted_expires_ms > qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL))) {
> error_setg(errp, "Device %s is already in the "
> "process of unplug", id);
> return;