From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:56064) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1T4q3B-00017B-Js for qemu-devel@nongnu.org; Fri, 24 Aug 2012 05:19:34 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1T4q3A-0001hu-0x for qemu-devel@nongnu.org; Fri, 24 Aug 2012 05:19:33 -0400 Received: from mx1.redhat.com ([209.132.183.28]:41835) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1T4q39-0001hp-PQ for qemu-devel@nongnu.org; Fri, 24 Aug 2012 05:19:31 -0400 Date: Fri, 24 Aug 2012 12:20:42 +0300 From: "Michael S. Tsirkin" Message-ID: <20120824092042.GA12300@redhat.com> References: <5037182A.7080902@web.de> <20120824081136.GB7830@redhat.com> <50373825.6020007@web.de> <20120824083640.GD7830@redhat.com> <50373DB3.7080700@web.de> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline In-Reply-To: <50373DB3.7080700@web.de> Content-Transfer-Encoding: quoted-printable Subject: Re: [Qemu-devel] MSI-X bug with ivshmem since msix_reset moved to PCI List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Jan Kiszka Cc: Cam Macdonell , "qemu-devel@nongnu.org Developers" On Fri, Aug 24, 2012 at 10:39:15AM +0200, Jan Kiszka wrote: > On 2012-08-24 10:36, Michael S. Tsirkin wrote: > > On Fri, Aug 24, 2012 at 10:15:33AM +0200, Jan Kiszka wrote: > >> On 2012-08-24 10:11, Michael S. Tsirkin wrote: > >>> On Fri, Aug 24, 2012 at 07:59:06AM +0200, Jan Kiszka wrote: > >>>> On 2012-08-24 01:13, Cam Macdonell wrote: > >>>>> Hi Jan, > >>>>> > >>>>> I've bisected a bug in which MSI interrupts are not being deliver= ed to > >>>>> the following patch, where msix_reset was moved in tot he PCI cor= e. > >>>>> > >>>>> commit cbd2d4342b3d42ab33baa99f5b7a23491b5692f2 > >>>>> Author: Jan Kiszka > >>>>> Date: Tue May 15 20:09:56 2012 -0300 > >>>>> > >>>>> msi: Invoke msi/msix_reset from PCI core > >>>>> > >>>>> There is no point in pushing this burden to the devices, they= tend to > >>>>> forget to call them (like intel-hda, ahci, xhci did). Instead= , reset > >>>>> functions are now called from pci_device_reset. They do nothi= ng if > >>>>> MSI/MSI-X is not in use. > >>>>> > >>>>> I've been debugging and it seems that when msix_notify() is trigg= ered > >>>>> the second test in the "if" fails > >>>>> > >>>>> /* Send an MSI-X message */ > >>>>> void msix_notify(PCIDevice *dev, unsigned vector) > >>>>> { > >>>>> MSIMessage msg; > >>>>> > >>>>> if (vector >=3D dev->msix_entries_nr || !dev->msix_entry_used= [vector]) > >>>>> return; > >>>>> > >>>>> =E2=80=A6 > >>>>> } > >>>>> > >>>>> here is some MSI-X debugging statements > >>>>> > >>>>> msix_init > >>>>> IVSHMEM: msix initialized (1 vectors) > >>>>> IVSHMEM: using vector 0 > >>>>> IVSHMEM: ivshmem_reset > >>>>> IVSHMEM: using vector 0 > >>>>> msix_reset > >>>>> msix_free_irq_entries 0x7fd52d1cea20 > >>>>> > >>>>> msix_free_irq_entries() sets dev->msix_entries_nr to 0, so I thin= k it > >>>>> may be the cause. > >>>> > >>>> I suppose you mean it sets the msix_entry_used array to 0. > >>>> > >>>>> > >>>>> Shouldn't ivshmem's reset (which reenables the vectors) be trigge= red > >>>>> by the msix_reset? > >>>> > >>>> Actually, the whole msix vector usage tracking is useless today, t= his > >>>> just shows its downsides (in the absence of benefits). Megasas is > >>>> affected by this problem as well, virtio not as it calls msix_vect= or_use > >>>> during the configuration process the guest driver triggers. > >>>> > >>>> Two options: > >>>> - I can send my removal patch for msix_vector_use/unuse that I wa= s > >>>> only planning for 1.3 so far, and we kill this pitfall earlier. > >>>> - We re-add msix_vector_use calls to the affected device models f= or > >>>> 1.2 and drop them later again for 1.3 when removing usage track= ing. > >>>> [The third option to keep the usage tracking is a non-option for m= e. ;)] > >>>> > >>>> Michael? > >>> > >>> Second option seems more prudent to me. Can you send a patch pls? > >> > >> In fact, it's not as easy. ivshmem already tries to restore the usag= e > >> flag but fails due to reset handler ordering. I do not see ATM where > >> there is some "enable device" during re-initialization, at least for > >> ivshmem. Haven't checked megasas yet. > >> > >> I tend to think removing is simpler and less risky. Please have a lo= ok > >> at the patch I sent earlier. > >> > >> Jan > >> > >> > >=20 > > Actually virtio is the only one that changes vector use > > so the only one that needs to reset it. > >=20 > > I am thinking we should find a way to move vector use > > out from core to virtio-pci. > > But for now something like the below should do the trick. > > Untested unfortunately, will test virtio Sunday > > but would appreciate review and testing reports > > esp with ivshmem etc. > >=20 > > --> > >=20 > > msix: avoid need to use/unuse vectors for most devices > >=20 > > The facility to use/unuse vectors is helpful for virtio > > but little else since everyone just seems to use > > vectors in their init function. > >=20 > > Avoid clearing msix vector use info on reset and load. > > For virtio, clear it explicitly. > >=20 > > Signed-off-by: Michael S. Tsirkin > >=20 > > --- > >=20 > > diff --git a/hw/msix.c b/hw/msix.c > > index 800fc32..d040cc2 100644 > > --- a/hw/msix.c > > +++ b/hw/msix.c > > @@ -340,6 +340,15 @@ static void msix_free_irq_entries(PCIDevice *dev= ) > > } > > } > > =20 > > +static void msix_clear_all_vectors(PCIDevice *dev) > > +{ > > + int vector; > > + > > + for (vector =3D 0; vector < dev->msix_entries_nr; ++vector) { > > + msix_clr_pending(dev, vector); > > + } > > +} > > + > > /* Clean up resources for the device. */ > > void msix_uninit(PCIDevice *dev, MemoryRegion *table_bar, MemoryRegi= on *pba_bar) > > { > > @@ -394,7 +403,7 @@ void msix_load(PCIDevice *dev, QEMUFile *f) > > return; > > } > > =20 > > - msix_free_irq_entries(dev); > > + msix_clear_all_vectors(dev); > > qemu_get_buffer(f, dev->msix_table, n * PCI_MSIX_ENTRY_SIZE); > > qemu_get_buffer(f, dev->msix_pba, (n + 7) / 8); > > msix_update_function_masked(dev); > > @@ -440,7 +449,7 @@ void msix_reset(PCIDevice *dev) > > if (!msix_present(dev)) { > > return; > > } > > - msix_free_irq_entries(dev); > > + msix_clear_all_vectors(dev); > > dev->config[dev->msix_cap + MSIX_CONTROL_OFFSET] &=3D > > ~dev->wmask[dev->msix_cap + MSIX_CONTROL_OFFSET]; > > memset(dev->msix_table, 0, dev->msix_entries_nr * PCI_MSIX_ENTRY= _SIZE); > > diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c > > index 125eded..ca0b204 100644 > > --- a/hw/virtio-pci.c > > +++ b/hw/virtio-pci.c > > @@ -131,6 +131,7 @@ static int virtio_pci_load_config(void * opaque, = QEMUFile *f) > > if (ret) { > > return ret; > > } > > + msix_unuse_all_vectors(&proxy->pci_dev); > > msix_load(&proxy->pci_dev, f); > > if (msix_present(&proxy->pci_dev)) { > > qemu_get_be16s(f, &proxy->vdev->config_vector); > > @@ -246,6 +247,7 @@ void virtio_pci_reset(DeviceState *d) > > VirtIOPCIProxy *proxy =3D container_of(d, VirtIOPCIProxy, pci_de= v.qdev); > > virtio_pci_stop_ioeventfd(proxy); > > virtio_reset(proxy->vdev); > > + msix_unuse_all_vectors(&proxy->pci_dev); > > proxy->flags &=3D ~VIRTIO_PCI_FLAG_BUS_MASTER_BUG; > > } > > =20 > >=20 >=20 > This just prolongs the life of a wrong API, but I'm fine for 1.2 if it > helps. However, I will push on removing all this for 1.3. >=20 > Jan >=20 For 1.3 we'll move use tracking into virtio, yes. --=20 MST