Re: [PATCH 3/6] spapr: Introduce spapr_drc_reset_all()
On Fri, Dec 18, 2020 at 11:33:57AM +0100, Greg Kurz wrote: > No need to expose the way DRCs are traversed outside of spapr_drc.c. > > Signed-off-by: Greg Kurz Applied, thanks. > --- > include/hw/ppc/spapr_drc.h | 6 ++ > hw/ppc/spapr_drc.c | 31 + > hw/ppc/spapr_hcall.c | 40 ++ > 3 files changed, 43 insertions(+), 34 deletions(-) > > diff --git a/include/hw/ppc/spapr_drc.h b/include/hw/ppc/spapr_drc.h > index 5d80019f82e2..8982927d5c24 100644 > --- a/include/hw/ppc/spapr_drc.h > +++ b/include/hw/ppc/spapr_drc.h > @@ -245,6 +245,12 @@ int spapr_dt_drc(void *fdt, int offset, Object *owner, > uint32_t drc_type_mask); > void spapr_drc_attach(SpaprDrc *drc, DeviceState *d); > void spapr_drc_detach(SpaprDrc *drc); > > +/* > + * Reset all DRCs, causing pending hot-plug/unplug requests to complete. > + * Safely handles potential DRC removal (eg. PHBs or PCI bridges). > + */ > +void spapr_drc_reset_all(struct SpaprMachineState *spapr); > + > static inline bool spapr_drc_unplug_requested(SpaprDrc *drc) > { > return drc->unplug_requested; > diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c > index 5b5e2ac58a7e..a4d2608017c5 100644 > --- a/hw/ppc/spapr_drc.c > +++ b/hw/ppc/spapr_drc.c > @@ -949,6 +949,37 @@ out: > return ret; > } > > +void spapr_drc_reset_all(SpaprMachineState *spapr) > +{ > +Object *drc_container; > +ObjectProperty *prop; > +ObjectPropertyIterator iter; > + > +drc_container = container_get(object_get_root(), DRC_CONTAINER_PATH); > +restart: > +object_property_iter_init(&iter, drc_container); > +while ((prop = object_property_iter_next(&iter))) { > +SpaprDrc *drc; > + > +if (!strstart(prop->type, "link<", NULL)) { > +continue; > +} > +drc = SPAPR_DR_CONNECTOR(object_property_get_link(drc_container, > + prop->name, > + &error_abort)); > + > +/* > + * This will complete any pending plug/unplug requests. > + * In case of a unplugged PHB or PCI bridge, this will > + * cause some DRCs to be destroyed and thus potentially > + * invalidate the iterator. > + */ > +if (spapr_drc_reset(drc)) { > +goto restart; > +} > +} > +} > + > /* > * RTAS calls > */ > diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c > index aa22830ac4bd..e5dfc1ba7acc 100644 > --- a/hw/ppc/spapr_hcall.c > +++ b/hw/ppc/spapr_hcall.c > @@ -1632,39 +1632,6 @@ static uint32_t cas_check_pvr(PowerPCCPU *cpu, > uint32_t max_compat, > return best_compat; > } > > -static void spapr_handle_transient_dev_before_cas(SpaprMachineState *spapr) > -{ > -Object *drc_container; > -ObjectProperty *prop; > -ObjectPropertyIterator iter; > - > -drc_container = container_get(object_get_root(), "/dr-connector"); > -restart: > -object_property_iter_init(&iter, drc_container); > -while ((prop = object_property_iter_next(&iter))) { > -SpaprDrc *drc; > - > -if (!strstart(prop->type, "link<", NULL)) { > -continue; > -} > -drc = SPAPR_DR_CONNECTOR(object_property_get_link(drc_container, > - prop->name, > - &error_abort)); > - > -/* > - * This will complete any pending plug/unplug requests. > - * In case of a unplugged PHB or PCI bridge, this will > - * cause some DRCs to be destroyed and thus potentially > - * invalidate the iterator. > - */ > -if (spapr_drc_reset(drc)) { > -goto restart; > -} > -} > - > -spapr_clear_pending_hotplug_events(spapr); > -} > - > target_ulong do_client_architecture_support(PowerPCCPU *cpu, > SpaprMachineState *spapr, > target_ulong vec, > @@ -1822,7 +1789,12 @@ target_ulong do_client_architecture_support(PowerPCCPU > *cpu, > > spapr_irq_update_active_intc(spapr); > > -spapr_handle_transient_dev_before_cas(spapr); > +/* > + * Process all pending hot-plug/unplug requests now. An updated full > + * rendered FDT will be returned to the guest. > + */ > +spapr_drc_reset_all(spapr); > +spapr_clear_pending_hotplug_events(spapr); > > /* > * If spapr_machine_reset() did not set up a HPT but one is necessary -- David Gibson| I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson signature.asc Description: PGP signature
Re: [PATCH 3/6] spapr: Introduce spapr_drc_reset_all()
On 12/18/20 7:33 AM, Greg Kurz wrote: No need to expose the way DRCs are traversed outside of spapr_drc.c. Signed-off-by: Greg Kurz --- Reviewed-by: Daniel Henrique Barboza include/hw/ppc/spapr_drc.h | 6 ++ hw/ppc/spapr_drc.c | 31 + hw/ppc/spapr_hcall.c | 40 ++ 3 files changed, 43 insertions(+), 34 deletions(-) diff --git a/include/hw/ppc/spapr_drc.h b/include/hw/ppc/spapr_drc.h index 5d80019f82e2..8982927d5c24 100644 --- a/include/hw/ppc/spapr_drc.h +++ b/include/hw/ppc/spapr_drc.h @@ -245,6 +245,12 @@ int spapr_dt_drc(void *fdt, int offset, Object *owner, uint32_t drc_type_mask); void spapr_drc_attach(SpaprDrc *drc, DeviceState *d); void spapr_drc_detach(SpaprDrc *drc); +/* + * Reset all DRCs, causing pending hot-plug/unplug requests to complete. + * Safely handles potential DRC removal (eg. PHBs or PCI bridges). + */ +void spapr_drc_reset_all(struct SpaprMachineState *spapr); + static inline bool spapr_drc_unplug_requested(SpaprDrc *drc) { return drc->unplug_requested; diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c index 5b5e2ac58a7e..a4d2608017c5 100644 --- a/hw/ppc/spapr_drc.c +++ b/hw/ppc/spapr_drc.c @@ -949,6 +949,37 @@ out: return ret; } +void spapr_drc_reset_all(SpaprMachineState *spapr) +{ +Object *drc_container; +ObjectProperty *prop; +ObjectPropertyIterator iter; + +drc_container = container_get(object_get_root(), DRC_CONTAINER_PATH); +restart: +object_property_iter_init(&iter, drc_container); +while ((prop = object_property_iter_next(&iter))) { +SpaprDrc *drc; + +if (!strstart(prop->type, "link<", NULL)) { +continue; +} +drc = SPAPR_DR_CONNECTOR(object_property_get_link(drc_container, + prop->name, + &error_abort)); + +/* + * This will complete any pending plug/unplug requests. + * In case of a unplugged PHB or PCI bridge, this will + * cause some DRCs to be destroyed and thus potentially + * invalidate the iterator. + */ +if (spapr_drc_reset(drc)) { +goto restart; +} +} +} + /* * RTAS calls */ diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index aa22830ac4bd..e5dfc1ba7acc 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -1632,39 +1632,6 @@ static uint32_t cas_check_pvr(PowerPCCPU *cpu, uint32_t max_compat, return best_compat; } -static void spapr_handle_transient_dev_before_cas(SpaprMachineState *spapr) -{ -Object *drc_container; -ObjectProperty *prop; -ObjectPropertyIterator iter; - -drc_container = container_get(object_get_root(), "/dr-connector"); -restart: -object_property_iter_init(&iter, drc_container); -while ((prop = object_property_iter_next(&iter))) { -SpaprDrc *drc; - -if (!strstart(prop->type, "link<", NULL)) { -continue; -} -drc = SPAPR_DR_CONNECTOR(object_property_get_link(drc_container, - prop->name, - &error_abort)); - -/* - * This will complete any pending plug/unplug requests. - * In case of a unplugged PHB or PCI bridge, this will - * cause some DRCs to be destroyed and thus potentially - * invalidate the iterator. - */ -if (spapr_drc_reset(drc)) { -goto restart; -} -} - -spapr_clear_pending_hotplug_events(spapr); -} - target_ulong do_client_architecture_support(PowerPCCPU *cpu, SpaprMachineState *spapr, target_ulong vec, @@ -1822,7 +1789,12 @@ target_ulong do_client_architecture_support(PowerPCCPU *cpu, spapr_irq_update_active_intc(spapr); -spapr_handle_transient_dev_before_cas(spapr); +/* + * Process all pending hot-plug/unplug requests now. An updated full + * rendered FDT will be returned to the guest. + */ +spapr_drc_reset_all(spapr); +spapr_clear_pending_hotplug_events(spapr); /* * If spapr_machine_reset() did not set up a HPT but one is necessary
[PATCH 3/6] spapr: Introduce spapr_drc_reset_all()
No need to expose the way DRCs are traversed outside of spapr_drc.c. Signed-off-by: Greg Kurz --- include/hw/ppc/spapr_drc.h | 6 ++ hw/ppc/spapr_drc.c | 31 + hw/ppc/spapr_hcall.c | 40 ++ 3 files changed, 43 insertions(+), 34 deletions(-) diff --git a/include/hw/ppc/spapr_drc.h b/include/hw/ppc/spapr_drc.h index 5d80019f82e2..8982927d5c24 100644 --- a/include/hw/ppc/spapr_drc.h +++ b/include/hw/ppc/spapr_drc.h @@ -245,6 +245,12 @@ int spapr_dt_drc(void *fdt, int offset, Object *owner, uint32_t drc_type_mask); void spapr_drc_attach(SpaprDrc *drc, DeviceState *d); void spapr_drc_detach(SpaprDrc *drc); +/* + * Reset all DRCs, causing pending hot-plug/unplug requests to complete. + * Safely handles potential DRC removal (eg. PHBs or PCI bridges). + */ +void spapr_drc_reset_all(struct SpaprMachineState *spapr); + static inline bool spapr_drc_unplug_requested(SpaprDrc *drc) { return drc->unplug_requested; diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c index 5b5e2ac58a7e..a4d2608017c5 100644 --- a/hw/ppc/spapr_drc.c +++ b/hw/ppc/spapr_drc.c @@ -949,6 +949,37 @@ out: return ret; } +void spapr_drc_reset_all(SpaprMachineState *spapr) +{ +Object *drc_container; +ObjectProperty *prop; +ObjectPropertyIterator iter; + +drc_container = container_get(object_get_root(), DRC_CONTAINER_PATH); +restart: +object_property_iter_init(&iter, drc_container); +while ((prop = object_property_iter_next(&iter))) { +SpaprDrc *drc; + +if (!strstart(prop->type, "link<", NULL)) { +continue; +} +drc = SPAPR_DR_CONNECTOR(object_property_get_link(drc_container, + prop->name, + &error_abort)); + +/* + * This will complete any pending plug/unplug requests. + * In case of a unplugged PHB or PCI bridge, this will + * cause some DRCs to be destroyed and thus potentially + * invalidate the iterator. + */ +if (spapr_drc_reset(drc)) { +goto restart; +} +} +} + /* * RTAS calls */ diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index aa22830ac4bd..e5dfc1ba7acc 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -1632,39 +1632,6 @@ static uint32_t cas_check_pvr(PowerPCCPU *cpu, uint32_t max_compat, return best_compat; } -static void spapr_handle_transient_dev_before_cas(SpaprMachineState *spapr) -{ -Object *drc_container; -ObjectProperty *prop; -ObjectPropertyIterator iter; - -drc_container = container_get(object_get_root(), "/dr-connector"); -restart: -object_property_iter_init(&iter, drc_container); -while ((prop = object_property_iter_next(&iter))) { -SpaprDrc *drc; - -if (!strstart(prop->type, "link<", NULL)) { -continue; -} -drc = SPAPR_DR_CONNECTOR(object_property_get_link(drc_container, - prop->name, - &error_abort)); - -/* - * This will complete any pending plug/unplug requests. - * In case of a unplugged PHB or PCI bridge, this will - * cause some DRCs to be destroyed and thus potentially - * invalidate the iterator. - */ -if (spapr_drc_reset(drc)) { -goto restart; -} -} - -spapr_clear_pending_hotplug_events(spapr); -} - target_ulong do_client_architecture_support(PowerPCCPU *cpu, SpaprMachineState *spapr, target_ulong vec, @@ -1822,7 +1789,12 @@ target_ulong do_client_architecture_support(PowerPCCPU *cpu, spapr_irq_update_active_intc(spapr); -spapr_handle_transient_dev_before_cas(spapr); +/* + * Process all pending hot-plug/unplug requests now. An updated full + * rendered FDT will be returned to the guest. + */ +spapr_drc_reset_all(spapr); +spapr_clear_pending_hotplug_events(spapr); /* * If spapr_machine_reset() did not set up a HPT but one is necessary -- 2.26.2