aboutsummaryrefslogtreecommitdiff
path: root/hw/usb
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2012-12-14 14:35:31 +0100
committerGerd Hoffmann <kraxel@redhat.com>2013-01-07 12:57:23 +0100
commit52c15e5986cd0f6531a2989a81a964f77b4ed9c2 (patch)
treea809cb1939da313c5e3e31168439c9369e377aa8 /hw/usb
parent9359a58b122187964d7465d48165680eadbf69d3 (diff)
ehci: Further speedup rescanning if async schedule after raising an interrupt
I tried lowering the time between raising an interrupt and rescanning the async schedule to see if the guest has queued a new transfer before, but that did not have any positive effect. I now believe the cause for this is that lowering this time made it more likely to hit the 1 ms interrupt threshold penalty for the next packet, as described in my "ehci: Use uframe precision for interrupt threshold checking" commit. Now that we do interrupt threshold handling with uframe precision, futher lowering this time from .5 to .25 ms gives an extra 15% improvement in speed (MB/s) reading from a simple USB-2.0 thumb-drive. While at it also properly set the int_req_by_async flag for short packet completions. Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Diffstat (limited to 'hw/usb')
-rw-r--r--hw/usb/hcd-ehci.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
index efa1d778e3..8da4b6a6d2 100644
--- a/hw/usb/hcd-ehci.c
+++ b/hw/usb/hcd-ehci.c
@@ -1347,6 +1347,9 @@ static void ehci_execute_complete(EHCIQueue *q)
if (tbytes) {
/* 4.15.1.2 must raise int on a short input packet */
ehci_raise_irq(q->ehci, USBSTS_INT);
+ if (q->async) {
+ q->ehci->int_req_by_async = true;
+ }
}
} else {
tbytes = 0;
@@ -2337,7 +2340,7 @@ static void ehci_frame_timer(void *opaque)
/* If we've raised int, we speed up the timer, so that we quickly
* notice any new packets queued up in response */
if (ehci->int_req_by_async && (ehci->usbsts & USBSTS_INT)) {
- expire_time = t_now + get_ticks_per_sec() / (FRAME_TIMER_FREQ * 2);
+ expire_time = t_now + get_ticks_per_sec() / (FRAME_TIMER_FREQ * 4);
ehci->int_req_by_async = false;
} else {
expire_time = t_now + (get_ticks_per_sec()