From 6b4e9dd4815e3bfde2debbde48d770caa284ac2e Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Wed, 29 Feb 2012 12:39:23 +0100 Subject: [PATCH 08/35] usb-redir: Try to keep our buffer size near the target size RH-Author: Gerd Hoffmann Message-id: <1330519171-24231-9-git-send-email-kraxel@redhat.com> Patchwork-id: 37773 O-Subject: [RHEL-6.3 qemu-kvm PATCH v2 08/16] usb-redir: Try to keep our buffer size near the target size Bugzilla: 758104 RH-Acked-by: Paolo Bonzini RH-Acked-by: Markus Armbruster RH-Acked-by: Alex Williamson Before this patch we would allow the (iso) buffer to grow unlimited (and it would under certain circumstances) leading to way too high latencies for iso data streams. Signed-off-by: Hans de Goede Signed-off-by: Gerd Hoffmann (cherry picked from commit 81fd7b7495d2a4c92483ed14075e376729c94ab4) Conflicts: usb-redir.c --- usb-redir.c | 30 +++++++++++++++++++++++++++--- 1 files changed, 27 insertions(+), 3 deletions(-) Signed-off-by: Michal Novotny --- usb-redir.c | 30 +++++++++++++++++++++++++++--- 1 files changed, 27 insertions(+), 3 deletions(-) diff --git a/usb-redir.c b/usb-redir.c index 4d10d25..738ec4f 100644 --- a/usb-redir.c +++ b/usb-redir.c @@ -61,6 +61,7 @@ struct endp_data { uint8_t interrupt_started; uint8_t interrupt_error; uint8_t bufpq_prefilled; + uint8_t bufpq_dropping_packets; QTAILQ_HEAD(, buf_packet) bufpq; int bufpq_size; int bufpq_target_size; @@ -290,16 +291,34 @@ static void usbredir_cancel_packet(USBDevice *udev, USBPacket *p) } } -static struct buf_packet *bufp_alloc(USBRedirDevice *dev, +static void bufp_alloc(USBRedirDevice *dev, uint8_t *data, int len, int status, uint8_t ep) { - struct buf_packet *bufp = qemu_malloc(sizeof(struct buf_packet)); + struct buf_packet *bufp; + + if (!dev->endpoint[EP2I(ep)].bufpq_dropping_packets && + dev->endpoint[EP2I(ep)].bufpq_size > + 2 * dev->endpoint[EP2I(ep)].bufpq_target_size) { + DPRINTF("bufpq overflow, dropping packets ep %02X\n", ep); + dev->endpoint[EP2I(ep)].bufpq_dropping_packets = 1; + } + /* Since we're interupting the stream anyways, drop enough packets to get + back to our target buffer size */ + if (dev->endpoint[EP2I(ep)].bufpq_dropping_packets) { + if (dev->endpoint[EP2I(ep)].bufpq_size > + dev->endpoint[EP2I(ep)].bufpq_target_size) { + free(data); + return; + } + dev->endpoint[EP2I(ep)].bufpq_dropping_packets = 0; + } + + bufp = qemu_malloc(sizeof(struct buf_packet)); bufp->data = data; bufp->len = len; bufp->status = status; QTAILQ_INSERT_TAIL(&dev->endpoint[EP2I(ep)].bufpq, bufp, next); dev->endpoint[EP2I(ep)].bufpq_size++; - return bufp; } static void bufp_free(USBRedirDevice *dev, struct buf_packet *bufp, @@ -379,6 +398,7 @@ static int usbredir_handle_iso_data(USBRedirDevice *dev, USBPacket *p, DPRINTF("iso stream started ep %02X\n", ep); dev->endpoint[EP2I(ep)].iso_started = 1; dev->endpoint[EP2I(ep)].bufpq_prefilled = 0; + dev->endpoint[EP2I(ep)].bufpq_dropping_packets = 0; } if (ep & USB_DIR_IN) { @@ -500,6 +520,10 @@ static int usbredir_handle_interrupt_data(USBRedirDevice *dev, usbredirparser_do_write(dev->parser); DPRINTF("interrupt recv started ep %02X\n", ep); dev->endpoint[EP2I(ep)].interrupt_started = 1; + /* We don't really want to drop interrupt packets ever, but + having some upper limit to how much we buffer is good. */ + dev->endpoint[EP2I(ep)].bufpq_target_size = 1000; + dev->endpoint[EP2I(ep)].bufpq_dropping_packets = 0; } intp = QTAILQ_FIRST(&dev->endpoint[EP2I(ep)].bufpq); -- 1.7.7.6