qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Michael Roth <mdroth@linux.vnet.ibm.com>
To: Gerd Hoffmann <kraxel@redhat.com>, qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH 05/10] xhci: emulate intr endpoint intervals correctly
Date: Tue, 24 Sep 2013 19:55:35 -0500	[thread overview]
Message-ID: <20130925005535.25429.95578@loki> (raw)
In-Reply-To: <1377693786-10844-7-git-send-email-kraxel@redhat.com>

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 <kraxel@redhat.com>
> ---
>  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 = bmRequestType & USB_DIR_IN;
>      xfer->iso_xfer = false;
> +    xfer->timed_xfer = 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 = ((mfindex + epctx->interval - 1) &
> +                     ~(epctx->interval-1));
> +    uint64_t kick = epctx->mfindex_last + epctx->interval;
> +
> +    assert(epctx->interval != 0);
> +    xfer->mfindex_kick = 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, XHCITransfer *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 mfindex)
>  {
>      if (xfer->mfindex_kick > mfindex) {
>          timer_mod(epctx->kick_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
> @@ -1883,18 +1896,30 @@ static int xhci_submit(XHCIState *xhci, XHCITransfer *xfer, XHCIEPContext *epctx
>      switch(epctx->type) {
>      case ET_INTR_OUT:
>      case ET_INTR_IN:
> +        xfer->pkts = 0;
> +        xfer->iso_xfer = false;
> +        xfer->timed_xfer = true;
> +        mfindex = 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 = 0;
>          xfer->iso_xfer = false;
> +        xfer->timed_xfer = false;
>          break;
>      case ET_ISO_OUT:
>      case ET_ISO_IN:
>          xfer->pkts = 1;
>          xfer->iso_xfer = true;
> +        xfer->timed_xfer = true;
>          mfindex = 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, unsigned 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 = 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 = 0;
> +            xfer->running_retry = 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 = (epctx->next_xfer + 1) % TD_QUEUE;
>                  ep = xfer->packet.ep;
>              } else {
> -                if (!xfer->iso_xfer) {
> +                if (!xfer->timed_xfer) {
>                      fprintf(stderr, "xhci: error firing data transfer\n");
>                  }
>              }
> -- 
> 1.8.3.1

  reply	other threads:[~2013-09-25  0:55 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-08-28 12:42 [Qemu-devel] [PATCH 00/10] usb: a bunch of bugfixes Gerd Hoffmann
2013-08-28 12:42 ` [Qemu-devel] [PATCH 01/10] xhci: remove leftover debug printf Gerd Hoffmann
2013-08-28 12:42 ` [Qemu-devel] [PATCH 02/10] xhci: add tracepoint for endpoint state changes Gerd Hoffmann
2013-08-28 12:42 ` [Qemu-devel] [PATCH 03/10] xhci: add port to slot_address tracepoint Gerd Hoffmann
2013-08-28 12:43 ` [Qemu-devel] [PATCH 04/10] xhci: fix endpoint interval calculation Gerd Hoffmann
2013-08-28 12:43 ` [Qemu-devel] [PATCH 05/10] xhci: emulate intr endpoint intervals correctly Gerd Hoffmann
2013-09-25  0:55   ` Michael Roth [this message]
2013-09-25  6:27     ` Gerd Hoffmann
2013-08-28 12:43 ` [Qemu-devel] [PATCH 06/10] xhci: reset port when disabling slot Gerd Hoffmann
2013-08-28 12:43 ` [Qemu-devel] [PATCH 07/10] uas: add property for request logging Gerd Hoffmann
2013-08-28 12:43 ` [Qemu-devel] [PATCH 08/10] usb: parallelize usb3 streams Gerd Hoffmann
2013-08-28 12:43 ` [Qemu-devel] [PATCH 09/10] usb-hub: add tracepoint for status reports Gerd Hoffmann
2013-08-28 12:43 ` [Qemu-devel] [PATCH 10/10] Revert "usb-hub: report status changes only once" Gerd Hoffmann
2013-08-28 15:13   ` Hans de Goede
2013-08-28 15:30     ` Gerd Hoffmann

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20130925005535.25429.95578@loki \
    --to=mdroth@linux.vnet.ibm.com \
    --cc=kraxel@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).