Message ID | 1455705833-17682-9-git-send-email-caoj.fnst@cn.fujitsu.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Wed, Feb 17, 2016 at 06:43:52PM +0800, Cao jin wrote: > From: Chen Fan <chen.fan.fnst@cn.fujitsu.com> > > avoid multi-reset host bus, we introduce sequence id to specify which > bus is resetting. and if one of the dependent devices has done a reset. > the others should skip. > > Signed-off-by: Chen Fan <chen.fan.fnst@cn.fujitsu.com> I don't see why it's needed. All devices on same bus always undergo bus reset together. Just select a representative (e.g. smallest devfn) and reset from that. > --- > hw/vfio/pci.c | 14 ++++++++++++++ > hw/vfio/pci.h | 3 +++ > 2 files changed, 17 insertions(+) > > diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c > index b900f70..5b885e7 100644 > --- a/hw/vfio/pci.c > +++ b/hw/vfio/pci.c > @@ -1951,6 +1951,8 @@ static int vfio_check_host_bus_reset(VFIOPCIDevice *vdev) > /* List all affected devices by bus reset */ > devices = &info->devices[0]; > > + vdev->single_depend_dev = (info->count == 1); > + > /* Verify that we have all the groups required */ > for (i = 0; i < info->count; i++) { > PCIHostDeviceAddress host; > @@ -2283,6 +2285,7 @@ static int vfio_pci_hot_reset(VFIOPCIDevice *vdev, bool single) > > vfio_pci_pre_reset(vdev); > vdev->vbasedev.needs_reset = false; > + vdev->last_bus_reset_seqid = vdev->pdev.bus->reset_seqid; > > ret = vfio_get_hot_reset_info(vdev, &info); > if (ret) { > @@ -2344,6 +2347,7 @@ static int vfio_pci_hot_reset(VFIOPCIDevice *vdev, bool single) > } > vfio_pci_pre_reset(tmp); > tmp->vbasedev.needs_reset = false; > + tmp->last_bus_reset_seqid = vdev->pdev.bus->reset_seqid; > multi = true; > break; > } > @@ -3040,6 +3044,16 @@ static void vfio_pci_reset(DeviceState *dev) > > trace_vfio_pci_reset(vdev->vbasedev.name); > > + /* if need to do a hot reset */ > + if (pdev->bus->bus_in_reset) { > + if (vdev->last_bus_reset_seqid == pdev->bus->reset_seqid) { > + return; > + } else if ((vdev->features & VFIO_FEATURE_ENABLE_AER)) { > + vfio_pci_hot_reset(vdev, vdev->single_depend_dev); > + return; > + } > + } > + > vfio_pci_pre_reset(vdev); > > if (vdev->resetfn && !vdev->resetfn(vdev)) { > diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h > index bf9e93c..684931d 100644 > --- a/hw/vfio/pci.h > +++ b/hw/vfio/pci.h > @@ -144,6 +144,9 @@ typedef struct VFIOPCIDevice { > bool no_kvm_msi; > bool no_kvm_msix; > > + bool single_depend_dev; > + uint32_t last_bus_reset_seqid; > + > NotifierWithReturn hotplug_notifier; > } VFIOPCIDevice; > > -- > 1.9.3 > >
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c index b900f70..5b885e7 100644 --- a/hw/vfio/pci.c +++ b/hw/vfio/pci.c @@ -1951,6 +1951,8 @@ static int vfio_check_host_bus_reset(VFIOPCIDevice *vdev) /* List all affected devices by bus reset */ devices = &info->devices[0]; + vdev->single_depend_dev = (info->count == 1); + /* Verify that we have all the groups required */ for (i = 0; i < info->count; i++) { PCIHostDeviceAddress host; @@ -2283,6 +2285,7 @@ static int vfio_pci_hot_reset(VFIOPCIDevice *vdev, bool single) vfio_pci_pre_reset(vdev); vdev->vbasedev.needs_reset = false; + vdev->last_bus_reset_seqid = vdev->pdev.bus->reset_seqid; ret = vfio_get_hot_reset_info(vdev, &info); if (ret) { @@ -2344,6 +2347,7 @@ static int vfio_pci_hot_reset(VFIOPCIDevice *vdev, bool single) } vfio_pci_pre_reset(tmp); tmp->vbasedev.needs_reset = false; + tmp->last_bus_reset_seqid = vdev->pdev.bus->reset_seqid; multi = true; break; } @@ -3040,6 +3044,16 @@ static void vfio_pci_reset(DeviceState *dev) trace_vfio_pci_reset(vdev->vbasedev.name); + /* if need to do a hot reset */ + if (pdev->bus->bus_in_reset) { + if (vdev->last_bus_reset_seqid == pdev->bus->reset_seqid) { + return; + } else if ((vdev->features & VFIO_FEATURE_ENABLE_AER)) { + vfio_pci_hot_reset(vdev, vdev->single_depend_dev); + return; + } + } + vfio_pci_pre_reset(vdev); if (vdev->resetfn && !vdev->resetfn(vdev)) { diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h index bf9e93c..684931d 100644 --- a/hw/vfio/pci.h +++ b/hw/vfio/pci.h @@ -144,6 +144,9 @@ typedef struct VFIOPCIDevice { bool no_kvm_msi; bool no_kvm_msix; + bool single_depend_dev; + uint32_t last_bus_reset_seqid; + NotifierWithReturn hotplug_notifier; } VFIOPCIDevice;