diff options
Diffstat (limited to 'hw/ppc')
-rw-r--r-- | hw/ppc/spapr.c | 4 | ||||
-rw-r--r-- | hw/ppc/spapr_drc.c | 13 |
2 files changed, 17 insertions, 0 deletions
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index b066df68cb..ecce8abf14 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -3724,6 +3724,10 @@ void spapr_core_unplug_request(HotplugHandler *hotplug_dev, DeviceState *dev, if (!spapr_drc_unplug_requested(drc)) { spapr_drc_unplug_request(drc); spapr_hotplug_req_remove_by_index(drc); + } else { + error_setg(errp, "core-id %d unplug is still pending, %d seconds " + "timeout remaining", + cc->core_id, spapr_drc_unplug_timeout_remaining_sec(drc)); } } diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c index 27adbc5c30..fd2e45640f 100644 --- a/hw/ppc/spapr_drc.c +++ b/hw/ppc/spapr_drc.c @@ -409,6 +409,8 @@ void spapr_drc_unplug_request(SpaprDrc *drc) drc->unplug_requested = true; + spapr_drc_start_unplug_timeout_timer(drc); + if (drc->state != drck->empty_state) { trace_spapr_drc_awaiting_quiesce(spapr_drc_index(drc)); return; @@ -417,6 +419,16 @@ void spapr_drc_unplug_request(SpaprDrc *drc) spapr_drc_release(drc); } +int spapr_drc_unplug_timeout_remaining_sec(SpaprDrc *drc) +{ + if (drc->unplug_requested && timer_pending(drc->unplug_timeout_timer)) { + return (qemu_timeout_ns_to_ms(drc->unplug_timeout_timer->expire_time) - + qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL)) / 1000; + } + + return 0; +} + bool spapr_drc_reset(SpaprDrc *drc) { SpaprDrcClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc); @@ -710,6 +722,7 @@ static void spapr_drc_cpu_class_init(ObjectClass *k, void *data) drck->drc_name_prefix = "CPU "; drck->release = spapr_core_release; drck->dt_populate = spapr_core_dt_populate; + drck->unplug_timeout_seconds = 15; } static void spapr_drc_pci_class_init(ObjectClass *k, void *data) |