From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:54892) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VOdON-0008Ba-TZ for qemu-devel@nongnu.org; Tue, 24 Sep 2013 20:55:56 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1VOdOE-0000xF-Sh for qemu-devel@nongnu.org; Tue, 24 Sep 2013 20:55:47 -0400 Received: from e8.ny.us.ibm.com ([32.97.182.138]:43513) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VOdOE-0000x4-O1 for qemu-devel@nongnu.org; Tue, 24 Sep 2013 20:55:38 -0400 Received: from /spool/local by e8.ny.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Tue, 24 Sep 2013 20:55:38 -0400 Received: from b01cxnp22033.gho.pok.ibm.com (b01cxnp22033.gho.pok.ibm.com [9.57.198.23]) by d01dlp01.pok.ibm.com (Postfix) with ESMTP id DF90538C8045 for ; Tue, 24 Sep 2013 20:55:35 -0400 (EDT) Received: from d01av05.pok.ibm.com (d01av05.pok.ibm.com [9.56.224.195]) by b01cxnp22033.gho.pok.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id r8P0taEE58720290 for ; Wed, 25 Sep 2013 00:55:36 GMT Received: from d01av05.pok.ibm.com (loopback [127.0.0.1]) by d01av05.pok.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id r8P0tahk007740 for ; Tue, 24 Sep 2013 20:55:36 -0400 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Michael Roth In-Reply-To: <1377693786-10844-7-git-send-email-kraxel@redhat.com> References: <1377693786-10844-1-git-send-email-kraxel@redhat.com> <1377693786-10844-7-git-send-email-kraxel@redhat.com> Message-ID: <20130925005535.25429.95578@loki> Date: Tue, 24 Sep 2013 19:55:35 -0500 Subject: Re: [Qemu-devel] [PATCH 05/10] xhci: emulate intr endpoint intervals correctly List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Gerd Hoffmann , qemu-devel@nongnu.org Quoting Gerd Hoffmann (2013-08-28 07:43:01) > Respect the interval for interrupt endpoints, so we don't finish > transfers as fast as possible but at the rate configured by the guest. > = > Fixes guest deadlocks triggered by interrupt storms. > = > Cc: Was this meant to go to qemu-stable? > Signed-off-by: Gerd Hoffmann > --- > hw/usb/hcd-xhci.c | 44 +++++++++++++++++++++++++++++++++++++------- > 1 file changed, 37 insertions(+), 7 deletions(-) > = > diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c > index 3826979..2e2eb55 100644 > --- a/hw/usb/hcd-xhci.c > +++ b/hw/usb/hcd-xhci.c > @@ -355,6 +355,7 @@ typedef struct XHCITransfer { > unsigned int streamid; > bool in_xfer; > bool iso_xfer; > + bool timed_xfer; > = > unsigned int trb_count; > unsigned int trb_alloced; > @@ -1820,6 +1821,7 @@ static int xhci_fire_ctl_transfer(XHCIState *xhci, = XHCITransfer *xfer) > = > xfer->in_xfer =3D bmRequestType & USB_DIR_IN; > xfer->iso_xfer =3D false; > + xfer->timed_xfer =3D false; > = > if (xhci_setup_packet(xfer) < 0) { > return -1; > @@ -1835,6 +1837,17 @@ static int xhci_fire_ctl_transfer(XHCIState *xhci,= XHCITransfer *xfer) > return 0; > } > = > +static void xhci_calc_intr_kick(XHCIState *xhci, XHCITransfer *xfer, > + XHCIEPContext *epctx, uint64_t mfindex) > +{ > + uint64_t asap =3D ((mfindex + epctx->interval - 1) & > + ~(epctx->interval-1)); > + uint64_t kick =3D epctx->mfindex_last + epctx->interval; > + > + assert(epctx->interval !=3D 0); > + xfer->mfindex_kick =3D MAX(asap, kick); > +} > + > static void xhci_calc_iso_kick(XHCIState *xhci, XHCITransfer *xfer, > XHCIEPContext *epctx, uint64_t mfindex) > { > @@ -1857,8 +1870,8 @@ static void xhci_calc_iso_kick(XHCIState *xhci, XHC= ITransfer *xfer, > } > } > = > -static void xhci_check_iso_kick(XHCIState *xhci, XHCITransfer *xfer, > - XHCIEPContext *epctx, uint64_t mfindex) > +static void xhci_check_intr_iso_kick(XHCIState *xhci, XHCITransfer *xfer, > + XHCIEPContext *epctx, uint64_t mfin= dex) > { > if (xfer->mfindex_kick > mfindex) { > timer_mod(epctx->kick_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUA= L) + > @@ -1883,18 +1896,30 @@ static int xhci_submit(XHCIState *xhci, XHCITrans= fer *xfer, XHCIEPContext *epctx > switch(epctx->type) { > case ET_INTR_OUT: > case ET_INTR_IN: > + xfer->pkts =3D 0; > + xfer->iso_xfer =3D false; > + xfer->timed_xfer =3D true; > + mfindex =3D xhci_mfindex_get(xhci); > + xhci_calc_intr_kick(xhci, xfer, epctx, mfindex); > + xhci_check_intr_iso_kick(xhci, xfer, epctx, mfindex); > + if (xfer->running_retry) { > + return -1; > + } > + break; > case ET_BULK_OUT: > case ET_BULK_IN: > xfer->pkts =3D 0; > xfer->iso_xfer =3D false; > + xfer->timed_xfer =3D false; > break; > case ET_ISO_OUT: > case ET_ISO_IN: > xfer->pkts =3D 1; > xfer->iso_xfer =3D true; > + xfer->timed_xfer =3D true; > mfindex =3D xhci_mfindex_get(xhci); > xhci_calc_iso_kick(xhci, xfer, epctx, mfindex); > - xhci_check_iso_kick(xhci, xfer, epctx, mfindex); > + xhci_check_intr_iso_kick(xhci, xfer, epctx, mfindex); > if (xfer->running_retry) { > return -1; > } > @@ -1955,13 +1980,18 @@ static void xhci_kick_ep(XHCIState *xhci, unsigne= d int slotid, > = > trace_usb_xhci_xfer_retry(xfer); > assert(xfer->running_retry); > - if (xfer->iso_xfer) { > - /* retry delayed iso transfer */ > + if (xfer->timed_xfer) { > + /* time to kick the transfer? */ > mfindex =3D xhci_mfindex_get(xhci); > - xhci_check_iso_kick(xhci, xfer, epctx, mfindex); > + xhci_check_intr_iso_kick(xhci, xfer, epctx, mfindex); > if (xfer->running_retry) { > return; > } > + xfer->timed_xfer =3D 0; > + xfer->running_retry =3D 1; > + } > + if (xfer->iso_xfer) { > + /* retry iso transfer */ > if (xhci_setup_packet(xfer) < 0) { > return; > } > @@ -2047,7 +2077,7 @@ static void xhci_kick_ep(XHCIState *xhci, unsigned = int slotid, > epctx->next_xfer =3D (epctx->next_xfer + 1) % TD_QUEUE; > ep =3D xfer->packet.ep; > } else { > - if (!xfer->iso_xfer) { > + if (!xfer->timed_xfer) { > fprintf(stderr, "xhci: error firing data transfer\n"= ); > } > } > -- = > 1.8.3.1