From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58254) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1adhbq-0008Uf-SS for qemu-devel@nongnu.org; Wed, 09 Mar 2016 12:09:22 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1adhbn-0000Ah-LG for qemu-devel@nongnu.org; Wed, 09 Mar 2016 12:09:18 -0500 Received: from mx1.redhat.com ([209.132.183.28]:58187) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1adhbn-0000Ac-D5 for qemu-devel@nongnu.org; Wed, 09 Mar 2016 12:09:15 -0500 Date: Wed, 9 Mar 2016 10:09:11 -0700 From: Alex Williamson Message-ID: <20160309100911.79e8211f@t450s.home> In-Reply-To: <20160309183411-mutt-send-email-mst@redhat.com> References: <1457320984-6540-1-git-send-email-caoj.fnst@cn.fujitsu.com> <1457320984-6540-10-git-send-email-caoj.fnst@cn.fujitsu.com> <20160309183411-mutt-send-email-mst@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Subject: Re: [Qemu-devel] [PATCH v2 09/11] vfio: vote a device to do host bus reset List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: "Michael S. Tsirkin" Cc: chen.fan.fnst@cn.fujitsu.com, izumi.taku@jp.fujitsu.com, Cao jin , qemu-devel@nongnu.org On Wed, 9 Mar 2016 18:39:51 +0200 "Michael S. Tsirkin" wrote: > On Mon, Mar 07, 2016 at 11:23:02AM +0800, Cao jin wrote: > > From: Chen Fan > > > > Signed-off-by: Chen Fan > > --- > > hw/vfio/pci.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > > hw/vfio/pci.h | 1 + > > 2 files changed, 58 insertions(+) > > > > diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c > > index 24848c9..8e902d2 100644 > > --- a/hw/vfio/pci.c > > +++ b/hw/vfio/pci.c > > @@ -1937,6 +1937,8 @@ static void vfio_check_host_bus_reset(VFIOPCIDevice *vdev, Error **errp) > > /* 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; > > @@ -2998,6 +3000,49 @@ static void vfio_exitfn(PCIDevice *pdev) > > vfio_unregister_bars(vdev); > > } > > > > +static VFIOPCIDevice *vfio_pci_get_do_reset_device(VFIOPCIDevice *vdev) > > +{ > > + struct vfio_pci_hot_reset_info *info = NULL; > > + struct vfio_pci_dependent_device *devices; > > + VFIOGroup *group; > > + VFIODevice *vbasedev_iter; > > + int ret; > > + > > + ret = vfio_get_hot_reset_info(vdev, &info); > > + if (ret) { > > + error_report("vfio: Cannot enable AER for device %s," > > + " device does not support hot reset.", > > + vdev->vbasedev.name); > > + return NULL; > > + } > > + > > + devices = &info->devices[0]; > > + > > + QLIST_FOREACH(group, &vfio_group_list, next) { > > + if (group->groupid == devices[0].group_id) { > > + break; > > + } > > + } > > + > > + if (!group) { > > + error_report("vfio: Cannot enable AER for device %s, " > > + "depends on group %d which is not owned.", > > + vdev->vbasedev.name, devices[0].group_id); > > + return NULL; > > + } > > + > > + QLIST_FOREACH(vbasedev_iter, &group->device_list, next) { > > + if (vbasedev_iter->type != VFIO_DEVICE_TYPE_PCI || > > + !(vdev->features & VFIO_FEATURE_ENABLE_AER)) { > > + continue; > > + } > > + > > + return container_of(vbasedev_iter, VFIOPCIDevice, vbasedev); > > + } > > + > > + return NULL; > > +} > > + > > static void vfio_pci_reset(DeviceState *dev) > > { > > PCIDevice *pdev = DO_UPCAST(PCIDevice, qdev, dev); > > @@ -3005,6 +3050,18 @@ static void vfio_pci_reset(DeviceState *dev) > > > > trace_vfio_pci_reset(vdev->vbasedev.name); > > > > + if (pdev->bus->in_hot_reset) { > > After discussing this with Alex, I think what you > really are looking for is > if (dev->realized) > in order to skip hot reset when device is plugged-in > initially. Seems fragile, device_reset() also gets called via pci_device_reset() which would happen if we hooked up FLR to the device. That's clearly intended to be a function local reset, as is I believe the dc->reset itself, so assuming behavior based on states like dev->realized is likely to break. Either we need some external hints, like what's added here, or we need a separate callback for a bus reset. Thanks, Alex > > + VFIOPCIDevice *tmp; > > + > > + tmp = vfio_pci_get_do_reset_device(vdev); > > + if (tmp) { > > + if (tmp == vdev) { > > + 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 aff46c2..32bd31f 100644 > > --- a/hw/vfio/pci.h > > +++ b/hw/vfio/pci.h > > @@ -143,6 +143,7 @@ typedef struct VFIOPCIDevice { > > bool no_kvm_intx; > > bool no_kvm_msi; > > bool no_kvm_msix; > > + bool single_depend_dev; > > } VFIOPCIDevice; > > > > uint32_t vfio_pci_read_config(PCIDevice *pdev, uint32_t addr, int len); > > -- > > 1.9.3 > > > >