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

Hans de Goede c8dfc6
From d2901e4798cb106d5b265aa4e3ae05c06bf2bd1c Mon Sep 17 00:00:00 2001
Hans de Goede c8dfc6
From: Hans de Goede <hdegoede@redhat.com>
Hans de Goede c8dfc6
Date: Thu, 6 Sep 2012 17:10:48 +0200
Hans de Goede c8dfc6
Subject: [PATCH 360/366] ehci: Don't process too much frames in 1 timer tick
Hans de Goede c8dfc6
Hans de Goede c8dfc6
The Linux ehci isoc scheduling code fills the entire schedule ahead of
Hans de Goede c8dfc6
time minus 80 frames. If we make a large jump in where we are in the
Hans de Goede c8dfc6
schedule, ie 40 frames, then the scheduler all of a sudden will only have
Hans de Goede c8dfc6
40 frames left to work in, causing it to fail packet submissions
Hans de Goede c8dfc6
with error -27 (-EFBIG).
Hans de Goede c8dfc6
Hans de Goede c8dfc6
Note at first I had MAX_FR_PER_TICK set to 8, which works well with newer
Hans de Goede c8dfc6
Linux guest kernels, but not with older ones (such as the RHEL-6 kernel).
Hans de Goede c8dfc6
Hans de Goede c8dfc6
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Hans de Goede c8dfc6
---
Hans de Goede c8dfc6
 hw/usb/hcd-ehci.c | 9 +++++++++
Hans de Goede c8dfc6
 1 file changed, 9 insertions(+)
Hans de Goede c8dfc6
Hans de Goede c8dfc6
diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
Hans de Goede c8dfc6
index 30d2b56..5398544 100644
Hans de Goede c8dfc6
--- a/hw/usb/hcd-ehci.c
Hans de Goede c8dfc6
+++ b/hw/usb/hcd-ehci.c
Hans de Goede c8dfc6
@@ -140,6 +140,7 @@
Hans de Goede c8dfc6
 #define NB_PORTS         6        // Number of downstream ports
Hans de Goede c8dfc6
 #define BUFF_SIZE        5*4096   // Max bytes to transfer per transaction
Hans de Goede c8dfc6
 #define MAX_QH           100      // Max allowable queue heads in a chain
Hans de Goede c8dfc6
+#define MAX_FR_PER_TICK  4        /* Max frames to process in one timer tick */
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
 /*  Internal periodic / asynchronous schedule state machine states
Hans de Goede c8dfc6
  */
Hans de Goede c8dfc6
@@ -2460,6 +2461,14 @@ static void ehci_frame_timer(void *opaque)
Hans de Goede c8dfc6
             DPRINTF("WARNING - EHCI skipped %d frames\n", skipped_frames);
Hans de Goede c8dfc6
         }
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
+        /*
Hans de Goede c8dfc6
+         * Processing too much frames at once causes the Linux EHCI isoc
Hans de Goede c8dfc6
+         * scheduling code to fail packet re-submissions with -EFBIG.
Hans de Goede c8dfc6
+         */
Hans de Goede c8dfc6
+        if (frames > MAX_FR_PER_TICK) {
Hans de Goede c8dfc6
+            frames = MAX_FR_PER_TICK;
Hans de Goede c8dfc6
+        }
Hans de Goede c8dfc6
+
Hans de Goede c8dfc6
         for (i = 0; i < frames; i++) {
Hans de Goede c8dfc6
             ehci_update_frindex(ehci, 1);
Hans de Goede c8dfc6
             ehci_advance_periodic_state(ehci);
Hans de Goede c8dfc6
-- 
Hans de Goede c8dfc6
1.7.12
Hans de Goede c8dfc6