From: Gerd Hoffmann <kraxel@redhat.com>
To: qemu-devel@nongnu.org
Cc: Evgeny Yakovlev <eyakovlev@virtuozzo.com>,
"Denis V. Lunev" <den@openvz.org>,
Gerd Hoffmann <kraxel@redhat.com>
Subject: [Qemu-devel] [PULL 3/6] ehci: faster frame index calculation for skipped frames
Date: Wed, 3 Aug 2016 15:05:46 +0200 [thread overview]
Message-ID: <1470229549-32477-4-git-send-email-kraxel@redhat.com> (raw)
In-Reply-To: <1470229549-32477-1-git-send-email-kraxel@redhat.com>
From: Evgeny Yakovlev <eyakovlev@virtuozzo.com>
ehci_update_frindex takes time linearly proportional to a number
of uframes to calculate new frame index and raise FLR interrupts,
which is a problem for large amounts of uframes.
If we experience large delays between echi timer callbacks (i.e. because
other periodic handlers have taken a lot of time to complete) we
get a lot of skipped frames which then delay ehci timer callback more
and this leads to deadlocking the system when ehci schedules next
callback to be too soon.
Observable behaviour is qemu consuming 100% host CPU time while guest
is unresponsive. This misbehavior could happen for a while and QEMU does
not get out from this state automatically without the patch.
This change makes ehci_update_frindex execute in constant time.
Signed-off-by: Evgeny Yakovlev <eyakovlev@virtuozzo.com>
Signed-off-by: Denis V. Lunev <den@openvz.org>
Message-id: 1469638520-32706-1-git-send-email-den@openvz.org
CC: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/usb/hcd-ehci.c | 31 +++++++++++++++----------------
1 file changed, 15 insertions(+), 16 deletions(-)
diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
index 43a8f7a..b093db7 100644
--- a/hw/usb/hcd-ehci.c
+++ b/hw/usb/hcd-ehci.c
@@ -2206,29 +2206,28 @@ static void ehci_advance_periodic_state(EHCIState *ehci)
static void ehci_update_frindex(EHCIState *ehci, int uframes)
{
- int i;
-
if (!ehci_enabled(ehci) && ehci->pstate == EST_INACTIVE) {
return;
}
- for (i = 0; i < uframes; i++) {
- ehci->frindex++;
-
- if (ehci->frindex == 0x00002000) {
- ehci_raise_irq(ehci, USBSTS_FLR);
- }
+ /* Generate FLR interrupt if frame index rolls over 0x2000 */
+ if ((ehci->frindex % 0x2000) + uframes >= 0x2000) {
+ ehci_raise_irq(ehci, USBSTS_FLR);
+ }
- if (ehci->frindex == 0x00004000) {
- ehci_raise_irq(ehci, USBSTS_FLR);
- ehci->frindex = 0;
- if (ehci->usbsts_frindex >= 0x00004000) {
- ehci->usbsts_frindex -= 0x00004000;
- } else {
- ehci->usbsts_frindex = 0;
- }
+ /* How many times will frindex roll over 0x4000 with this frame count?
+ * usbsts_frindex is decremented by 0x4000 on rollover until it reaches 0
+ */
+ int rollovers = (ehci->frindex + uframes) / 0x4000;
+ if (rollovers > 0) {
+ if (ehci->usbsts_frindex >= (rollovers * 0x4000)) {
+ ehci->usbsts_frindex -= 0x4000 * rollovers;
+ } else {
+ ehci->usbsts_frindex = 0;
}
}
+
+ ehci->frindex = (ehci->frindex + uframes) % 0x4000;
}
static void ehci_frame_timer(void *opaque)
--
1.8.3.1
next prev parent reply other threads:[~2016-08-03 13:06 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-08-03 13:05 [Qemu-devel] [PULL for-2.7 0/6] usb patch queue Gerd Hoffmann
2016-08-03 13:05 ` [Qemu-devel] [PULL 1/6] wxx: Fix compiler warning for host-libusb.c Gerd Hoffmann
2016-08-03 13:05 ` [Qemu-devel] [PULL 2/6] wxx: Fix compilation of host-libusb.c Gerd Hoffmann
2016-08-03 13:05 ` Gerd Hoffmann [this message]
2016-08-03 13:05 ` [Qemu-devel] [PULL 4/6] xen: when removing a backend don't remove many of them Gerd Hoffmann
2016-08-03 13:05 ` [Qemu-devel] [PULL 5/6] xen: drain submit queue in xen-usb before removing device Gerd Hoffmann
2016-08-03 13:05 ` [Qemu-devel] [PULL 6/6] xen: use a common function for pv and hvm guest backend register calls Gerd Hoffmann
2016-08-03 15:02 ` [Qemu-devel] [PULL for-2.7 0/6] usb patch queue Peter Maydell
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=1470229549-32477-4-git-send-email-kraxel@redhat.com \
--to=kraxel@redhat.com \
--cc=den@openvz.org \
--cc=eyakovlev@virtuozzo.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).