From 4fdae1a75dfcd6699fce4cd5086d44b615fb4102 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 21 Sep 2012 18:57:35 -0300 Subject: [RHEL6 qemu-kvm PATCH 14/23] ehci: Don't process too much frames in 1 timer tick (v2) RH-Author: Hans de Goede Message-id: <1348253864-3050-14-git-send-email-hdegoede@redhat.com> Patchwork-id: 42190 O-Subject: [RHEL-6.4 qemu-kvm PATCH 13/22] ehci: Don't process too much frames in 1 timer tick (v2) Bugzilla: 805172 RH-Acked-by: Uri Lublin RH-Acked-by: Arnon Gilboa RH-Acked-by: Gerd Hoffmann The Linux ehci isoc scheduling code fills the entire schedule ahead of time minus 80 frames. If we make a large jump in where we are in the schedule, ie 40 frames, then the scheduler all of a sudden will only have 40 frames left to work in, causing it to fail packet submissions with error -27 (-EFBIG). Changes in v2: -Don't hardcode a maximum number of frames to process in one tick, instead: -Process a minimum number of frames to ensure we do eventually catch up -Stop (after the minimum number) when the guest has requested an irq Signed-off-by: Hans de Goede Signed-off-by: Gerd Hoffmann Upstream commit: 8f74ed1e43263293301031a10e440549bab19a6e Conflicts: hw/usb-ehci.c --- hw/usb-ehci.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) Signed-off-by: Eduardo Habkost --- hw/usb-ehci.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/hw/usb-ehci.c b/hw/usb-ehci.c index a9cbd68..d8c5757 100644 --- a/hw/usb-ehci.c +++ b/hw/usb-ehci.c @@ -133,6 +133,7 @@ #define NB_PORTS 6 // Number of downstream ports #define BUFF_SIZE 5*4096 // Max bytes to transfer per transaction #define MAX_QH 100 // Max allowable queue heads in a chain +#define MIN_FR_PER_TICK 3 // Min frames to process when catching up /* Internal periodic / asynchronous schedule state machine states */ @@ -2175,6 +2176,19 @@ static void ehci_frame_timer(void *opaque) } for (i = 0; i < frames; i++) { + /* + * If we're running behind schedule, we should not catch up + * too fast, as that will make some guests unhappy: + * 1) We must process a minimum of MIN_FR_PER_TICK frames, + * otherwise we will never catch up + * 2) Process frames until the guest has requested an irq (IOC) + */ + if (i >= MIN_FR_PER_TICK) { + ehci_commit_interrupt(ehci); + if ((ehci->usbsts & USBINTR_MASK) & ehci->usbintr) { + break; + } + } ehci_update_frindex(ehci, 1); ehci_advance_periodic_state(ehci); ehci->last_run_usec += FRAME_TIMER_USEC; -- 1.7.11.4