qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH] `qdev_free` when unplug a pci device


From: Markus Armbruster
Subject: Re: [Qemu-devel] [PATCH] `qdev_free` when unplug a pci device
Date: Wed, 23 Feb 2011 09:30:23 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1 (gnu/linux)

Isaku Yamahata <address@hidden> writes:

> On Tue, Feb 22, 2011 at 06:36:20PM +0100, William Dauchy wrote:
>>  `qdev_free` when unplug a pci device
>>  It resolves a bug when detaching/attaching a network device
>> 
>>  # virsh detach-interface dom0 network --mac 52:54:00:f6:84:ba
>>  Interface detached successfully
>> 
>>  # virsh attach-interface dom0 network default --mac 52:54:00:f6:84:ba
>>  error: Failed to attach interface
>>  error: internal error unable to execute QEMU command 'device_add': 
>> Duplicate ID 'net0' for device
>> 
>> A detached pci device was not freed of the list `qemu_device_opts`
>> ---
>>  hw/pci.c |    5 ++++-
>>  1 files changed, 4 insertions(+), 1 deletions(-)
>> 
>> diff --git a/hw/pci.c b/hw/pci.c
>> index 8b76cea..1e9a8f0 100644
>> --- a/hw/pci.c
>> +++ b/hw/pci.c
>> @@ -1671,13 +1671,16 @@ static int pci_unplug_device(DeviceState *qdev)
>>  {
>>      PCIDevice *dev = DO_UPCAST(PCIDevice, qdev, qdev);
>>      PCIDeviceInfo *info = container_of(qdev->info, PCIDeviceInfo, qdev);
>> +    int unplug;
>>  
>>      if (info->no_hotplug) {
>>          qerror_report(QERR_DEVICE_NO_HOTPLUG, info->qdev.name);
>>          return -1;
>>      }
>> -    return dev->bus->hotplug(dev->bus->hotplug_qdev, dev,
>> +    unplug = dev->bus->hotplug(dev->bus->hotplug_qdev, dev,
>>                               PCI_HOTPLUG_DISABLED);
>> +    qdev_free(qdev);
>
> Good catch.
> qdev_free() should be called only when unplug had succeeded.
> Although piix4 unplug always successes, pcie unplug may fail.
>
>> +    return unplug;
>>  }
>>  
>>  void pci_qdev_register(PCIDeviceInfo *info)

I don't think this patch is correct.  Let me explain.

Device hot unplug is *not* guaranteed to succeed.

For some buses, such as USB, it always succeeds immediately, i.e. when
the device_del monitor command finishes, the device is gone.  Live is
good.

But for PCI, device_del merely initiates the ACPI unplug rain dance.  It
doesn't wait for the dance to complete.  Why?  The dance can take an
unpredictable amount of time, including forever.

Problem: Subsequent device_add can fail if it reuses the qdev ID or PCI
slot, and the unplug has not yet completed (race condition), or it
failed.  Yes, Virginia, PCI hotplug *can* fail.

When unplug succeeds, the qdev is automatically destroyed.
pciej_write() does that for PIIX4.  Looks like pcie_cap_slot_event()
does it for PCIE.

Your patch adds a *second* qdev_free().  No good.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]