From patchwork Wed Aug 3 13:05:46 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gerd Hoffmann X-Patchwork-Id: 9261297 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 6BFF960754 for ; Wed, 3 Aug 2016 13:28:21 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5C74728541 for ; Wed, 3 Aug 2016 13:28:21 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 513E12856E; Wed, 3 Aug 2016 13:28:21 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id DCD8928541 for ; Wed, 3 Aug 2016 13:28:20 +0000 (UTC) Received: from localhost ([::1]:34578 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bUwDc-0003OG-1E for patchwork-qemu-devel@patchwork.kernel.org; Wed, 03 Aug 2016 09:28:20 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39985) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bUvrz-0008DU-Ci for qemu-devel@nongnu.org; Wed, 03 Aug 2016 09:06:00 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bUvrt-00084b-Pl for qemu-devel@nongnu.org; Wed, 03 Aug 2016 09:05:58 -0400 Received: from mx1.redhat.com ([209.132.183.28]:51930) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bUvrt-00084K-I6 for qemu-devel@nongnu.org; Wed, 03 Aug 2016 09:05:53 -0400 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 223224E027; Wed, 3 Aug 2016 13:05:53 +0000 (UTC) Received: from nilsson.home.kraxel.org (ovpn-116-18.ams2.redhat.com [10.36.116.18]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u73D5qha001342; Wed, 3 Aug 2016 09:05:52 -0400 Received: by nilsson.home.kraxel.org (Postfix, from userid 500) id 94E0780F63; Wed, 3 Aug 2016 15:05:51 +0200 (CEST) From: Gerd Hoffmann To: qemu-devel@nongnu.org Date: Wed, 3 Aug 2016 15:05:46 +0200 Message-Id: <1470229549-32477-4-git-send-email-kraxel@redhat.com> In-Reply-To: <1470229549-32477-1-git-send-email-kraxel@redhat.com> References: <1470229549-32477-1-git-send-email-kraxel@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Wed, 03 Aug 2016 13:05:53 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 3/6] ehci: faster frame index calculation for skipped frames X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: "Denis V. Lunev" , Evgeny Yakovlev , Gerd Hoffmann Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP From: Evgeny Yakovlev 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 Signed-off-by: Denis V. Lunev Message-id: 1469638520-32706-1-git-send-email-den@openvz.org CC: Gerd Hoffmann Signed-off-by: Gerd Hoffmann --- 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)