From patchwork Thu Oct 25 12:52:02 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gerd Hoffmann X-Patchwork-Id: 194223 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 2ED2B2C00AA for ; Fri, 26 Oct 2012 02:16:58 +1100 (EST) Received: from localhost ([::1]:55889 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TRMwB-0000EE-B2 for incoming@patchwork.ozlabs.org; Thu, 25 Oct 2012 08:53:27 -0400 Received: from eggs.gnu.org ([208.118.235.92]:59849) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TRMv5-0006oq-T3 for qemu-devel@nongnu.org; Thu, 25 Oct 2012 08:52:33 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TRMv2-0003CT-5H for qemu-devel@nongnu.org; Thu, 25 Oct 2012 08:52:19 -0400 Received: from mx1.redhat.com ([209.132.183.28]:8723) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TRMv1-0003BR-Lj for qemu-devel@nongnu.org; Thu, 25 Oct 2012 08:52:16 -0400 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q9PCqF9D030607 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Thu, 25 Oct 2012 08:52:15 -0400 Received: from rincewind.home.kraxel.org (ovpn-116-20.ams2.redhat.com [10.36.116.20]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id q9PCqCkx025863; Thu, 25 Oct 2012 08:52:14 -0400 Received: by rincewind.home.kraxel.org (Postfix, from userid 500) id E6E6C4128E; Thu, 25 Oct 2012 14:52:11 +0200 (CEST) From: Gerd Hoffmann To: qemu-devel@nongnu.org Date: Thu, 25 Oct 2012 14:52:02 +0200 Message-Id: <1351169529-10799-30-git-send-email-kraxel@redhat.com> In-Reply-To: <1351169529-10799-1-git-send-email-kraxel@redhat.com> References: <1351169529-10799-1-git-send-email-kraxel@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.12 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.132.183.28 Cc: Hans de Goede , Gerd Hoffmann Subject: [Qemu-devel] [PATCH 29/36] uhci: Always mark a queue valid when we encounter it X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Hans de Goede Before this patch we would not mark a queue valid when its head was a non-active td. This causes us to misbehave in the following scenario: 1) queue with multiple input transfers queued 2) We hit some latency issue, causing qemu to get behind processing frames 3) When qemu gets to run again, it notices the first transfer ends short, marking the head td non-active 4) It now processes 32+ frames in a row without giving the guest a chance to run since it is behind 5) valid is decreased to 0, causing the queue to get cancelled also cancelling already queued up further input transfers 6) guest gets to run, notices the inactive td, cleanups up further tds from the short transfer, and lets the queue continue at the first td of the next input transfer 7) we re-start the queue, issuing the second input transfer for the *second* time, and any data read by the first time we issued it has been lost Signed-off-by: Hans de Goede Signed-off-by: Gerd Hoffmann --- hw/usb/hcd-uhci.c | 15 +++++++-------- 1 files changed, 7 insertions(+), 8 deletions(-) diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c index 592ad8d..beeb3fd 100644 --- a/hw/usb/hcd-uhci.c +++ b/hw/usb/hcd-uhci.c @@ -183,6 +183,9 @@ static UHCIQueue *uhci_queue_new(UHCIState *s, uint32_t qh_addr, UHCI_TD *td, queue->ep = ep; QTAILQ_INIT(&queue->asyncs); QTAILQ_INSERT_HEAD(&s->queues, queue, next); + /* valid needs to be large enough to handle 10 frame delay + * for initial isochronous requests */ + queue->valid = 32; trace_usb_uhci_queue_add(queue->token); return queue; } @@ -819,6 +822,10 @@ static int uhci_handle_td(UHCIState *s, UHCIQueue *q, uint32_t qh_addr, } } + if (q) { + q->valid = 32; + } + /* Is active ? */ if (!(td->ctrl & TD_CTRL_ACTIVE)) { if (async) { @@ -836,9 +843,6 @@ static int uhci_handle_td(UHCIState *s, UHCIQueue *q, uint32_t qh_addr, } if (async) { - /* Already submitted */ - async->queue->valid = 32; - if (!async->done) return TD_RESULT_ASYNC_CONT; if (queuing) { @@ -860,11 +864,6 @@ static int uhci_handle_td(UHCIState *s, UHCIQueue *q, uint32_t qh_addr, } async = uhci_async_alloc(q, td_addr); - /* valid needs to be large enough to handle 10 frame delay - * for initial isochronous requests - */ - async->queue->valid = 32; - max_len = ((td->token >> 21) + 1) & 0x7ff; spd = (pid == USB_TOKEN_IN && (td->ctrl & TD_CTRL_SPD) != 0); usb_packet_setup(&async->packet, pid, q->ep, td_addr, spd,