Blame 0358-ehci-Don-t-process-too-much-frames-in-1-timer-tick-v.patch

Hans de Goede 93b7e3
From d1034a88fdd8ad693a5cc2cb75af946e1562ff09 Mon Sep 17 00:00:00 2001
Hans de Goede 93b7e3
From: Hans de Goede <hdegoede@redhat.com>
Hans de Goede 93b7e3
Date: Mon, 10 Sep 2012 12:38:21 +0200
Hans de Goede 93b7e3
Subject: [PATCH 358/369] ehci: Don't process too much frames in 1 timer tick
Hans de Goede 93b7e3
 (v2)
Hans de Goede 93b7e3
Hans de Goede 93b7e3
The Linux ehci isoc scheduling code fills the entire schedule ahead of
Hans de Goede 93b7e3
time minus 80 frames. If we make a large jump in where we are in the
Hans de Goede 93b7e3
schedule, ie 40 frames, then the scheduler all of a sudden will only have
Hans de Goede 93b7e3
40 frames left to work in, causing it to fail packet submissions
Hans de Goede 93b7e3
with error -27 (-EFBIG).
Hans de Goede 93b7e3
Hans de Goede 93b7e3
Changes in v2:
Hans de Goede 93b7e3
-Don't hardcode a maximum number of frames to process in one tick, instead:
Hans de Goede 93b7e3
 -Process a minimum number of frames to ensure we do eventually catch up
Hans de Goede 93b7e3
 -Stop (after the minimum number) when the guest has requested an irq
Hans de Goede 93b7e3
Hans de Goede 93b7e3
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Hans de Goede 93b7e3
---
Hans de Goede 93b7e3
 hw/usb/hcd-ehci.c | 14 ++++++++++++++
Hans de Goede 93b7e3
 1 file changed, 14 insertions(+)
Hans de Goede 93b7e3
Hans de Goede 93b7e3
diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
Hans de Goede 93b7e3
index 54273d7..6ce727c 100644
Hans de Goede 93b7e3
--- a/hw/usb/hcd-ehci.c
Hans de Goede 93b7e3
+++ b/hw/usb/hcd-ehci.c
Hans de Goede 93b7e3
@@ -139,6 +139,7 @@
Hans de Goede 93b7e3
 #define NB_PORTS         6        // Number of downstream ports
Hans de Goede 93b7e3
 #define BUFF_SIZE        5*4096   // Max bytes to transfer per transaction
Hans de Goede 93b7e3
 #define MAX_QH           100      // Max allowable queue heads in a chain
Hans de Goede 93b7e3
+#define MIN_FR_PER_TICK  3        // Min frames to process when catching up
Hans de Goede 93b7e3
 
Hans de Goede 93b7e3
 /*  Internal periodic / asynchronous schedule state machine states
Hans de Goede 93b7e3
  */
Hans de Goede 93b7e3
@@ -2448,6 +2449,19 @@ static void ehci_frame_timer(void *opaque)
Hans de Goede 93b7e3
         }
Hans de Goede 93b7e3
 
Hans de Goede 93b7e3
         for (i = 0; i < frames; i++) {
Hans de Goede 93b7e3
+            /* 
Hans de Goede 93b7e3
+             * If we're running behind schedule, we should not catch up
Hans de Goede 93b7e3
+             * too fast, as that will make some guests unhappy:
Hans de Goede 93b7e3
+             * 1) We must process a minimum of MIN_FR_PER_TICK frames,
Hans de Goede 93b7e3
+             *    otherwise we will never catch up
Hans de Goede 93b7e3
+             * 2) Process frames until the guest has requested an irq (IOC)
Hans de Goede 93b7e3
+             */
Hans de Goede 93b7e3
+            if (i >= MIN_FR_PER_TICK) {
Hans de Goede 93b7e3
+                ehci_commit_irq(ehci);
Hans de Goede 93b7e3
+                if ((ehci->usbsts & USBINTR_MASK) & ehci->usbintr) {
Hans de Goede 93b7e3
+                    break;
Hans de Goede 93b7e3
+                }
Hans de Goede 93b7e3
+            }
Hans de Goede 93b7e3
             ehci_update_frindex(ehci, 1);
Hans de Goede 93b7e3
             ehci_advance_periodic_state(ehci);
Hans de Goede 93b7e3
             ehci->last_run_ns += FRAME_TIMER_NS;
Hans de Goede 93b7e3
-- 
Hans de Goede 93b7e3
1.7.12
Hans de Goede 93b7e3