On Wed, 30 May 2018 16:13:32 +0200 David Hildenbrand <da...@redhat.com> wrote:
> On 30.05.2018 15:08, Igor Mammedov wrote: > > On Thu, 17 May 2018 10:15:17 +0200 > > David Hildenbrand <da...@redhat.com> wrote: > > > >> For multi stage hotplug handlers, we'll have to do some error handling > >> in some hotplug functions, so let's use a local error variable (except > >> for unplug requests). > > I'd split out introducing local error into separate patch > > so patch would do a single thing. > > > >> Also, add code to pass control to the final stage hotplug handler at the > >> parent bus. > > But I don't agree with generic > > "} else if ("dev->parent_bus && dev->parent_bus->hotplug_handler) {" > > forwarding, it's done by 3/14 for generic case and in case of > > special device that needs bus handler called from machine one, > > I'd suggest to do forwarding explicitly for that device only > > like we do with acpi_dev. > > I decided to do it that way because it is generic and results in nicer > recovery handling (e.g. in case pc_dimm plug fails, we can simply > rollback all (for now MemoryDevice) previous plug operations). rollback should be managed by the caller of pc_dimm plug directly, so it's not relevant here. > IMHO, the resulting code is easier to read. > > From this handling it is clear that > "if we reach the hotplug handler, and it is not some special device > plugged by the machine (CPU, PC_DIMM), pass it on to the actual hotplug > handler if any exists" I strongly disagree with that it's easier to deal with. You are basically duplicating already generalized code from qdev_get_hotplug_handler() back into boards. If a device doesn't have to be handled by machine handler, than qdev_get_hotplug_handler() must return its bus handler if any directly. So branch in question that your are copying is a dead one, pls drop it. > > > > > > >> Signed-off-by: David Hildenbrand <da...@redhat.com> > >> --- > >> hw/i386/pc.c | 39 +++++++++++++++++++++++++++++++-------- > >> 1 file changed, 31 insertions(+), 8 deletions(-) > >> > >> diff --git a/hw/i386/pc.c b/hw/i386/pc.c > >> index d768930d02..510076e156 100644 > >> --- a/hw/i386/pc.c > >> +++ b/hw/i386/pc.c > >> @@ -2007,19 +2007,32 @@ static void pc_cpu_pre_plug(HotplugHandler > >> *hotplug_dev, > >> static void pc_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev, > >> DeviceState *dev, Error **errp) > >> { > >> + Error *local_err = NULL; > >> + > >> + /* final stage hotplug handler */ > >> if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { > >> - pc_cpu_pre_plug(hotplug_dev, dev, errp); > >> + pc_cpu_pre_plug(hotplug_dev, dev, &local_err); > >> + } else if (dev->parent_bus && dev->parent_bus->hotplug_handler) { > >> + hotplug_handler_pre_plug(dev->parent_bus->hotplug_handler, dev, > >> + &local_err); > >> } > >> + error_propagate(errp, local_err); > >> } > >> > >> static void pc_machine_device_plug_cb(HotplugHandler *hotplug_dev, > >> DeviceState *dev, Error **errp) > >> { > >> + Error *local_err = NULL; > >> + > >> + /* final stage hotplug handler */ > >> if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { > >> - pc_dimm_plug(hotplug_dev, dev, errp); > >> + pc_dimm_plug(hotplug_dev, dev, &local_err); > >> } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { > >> - pc_cpu_plug(hotplug_dev, dev, errp); > >> + pc_cpu_plug(hotplug_dev, dev, &local_err); > >> + } else if (dev->parent_bus && dev->parent_bus->hotplug_handler) { > >> + hotplug_handler_plug(dev->parent_bus->hotplug_handler, dev, > >> &local_err); > >> } > >> + error_propagate(errp, local_err); > >> } > >> > >> static void pc_machine_device_unplug_request_cb(HotplugHandler > >> *hotplug_dev, > >> @@ -2029,7 +2042,10 @@ static void > >> pc_machine_device_unplug_request_cb(HotplugHandler *hotplug_dev, > >> pc_dimm_unplug_request(hotplug_dev, dev, errp); > >> } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { > >> pc_cpu_unplug_request_cb(hotplug_dev, dev, errp); > >> - } else { > >> + } else if (dev->parent_bus && dev->parent_bus->hotplug_handler) { > >> + hotplug_handler_unplug_request(dev->parent_bus->hotplug_handler, > >> dev, > >> + errp); > >> + } else if (!dev->parent_bus) { > >> error_setg(errp, "acpi: device unplug request for not supported > >> device" > >> " type: %s", object_get_typename(OBJECT(dev))); > >> } > >> @@ -2038,14 +2054,21 @@ static void > >> pc_machine_device_unplug_request_cb(HotplugHandler *hotplug_dev, > >> static void pc_machine_device_unplug_cb(HotplugHandler *hotplug_dev, > >> DeviceState *dev, Error **errp) > >> { > >> + Error *local_err = NULL; > >> + > >> + /* final stage hotplug handler */ > >> if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { > >> - pc_dimm_unplug(hotplug_dev, dev, errp); > >> + pc_dimm_unplug(hotplug_dev, dev, &local_err); > >> } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { > >> - pc_cpu_unplug_cb(hotplug_dev, dev, errp); > >> - } else { > >> - error_setg(errp, "acpi: device unplug for not supported device" > >> + pc_cpu_unplug_cb(hotplug_dev, dev, &local_err); > >> + } else if (dev->parent_bus && dev->parent_bus->hotplug_handler) { > >> + hotplug_handler_unplug(dev->parent_bus->hotplug_handler, dev, > >> + &local_err); > >> + } else if (!dev->parent_bus) { > >> + error_setg(&local_err, "acpi: device unplug for not supported > >> device" > >> " type: %s", object_get_typename(OBJECT(dev))); > >> } > >> + error_propagate(errp, local_err); > >> } > >> > >> static HotplugHandler *pc_get_hotpug_handler(MachineState *machine, > > > >