Blame 0104-usb-redir-Try-to-keep-our-buffer-size-near-the-targe.patch

Justin M. Forbes d4cdad
From b8e632d175063770655e75507de85ae873fa6c2d Mon Sep 17 00:00:00 2001
Justin M. Forbes d4cdad
From: Hans de Goede <hdegoede@redhat.com>
Justin M. Forbes d4cdad
Date: Tue, 20 Dec 2011 16:54:25 +0100
Justin M. Forbes d4cdad
Subject: [PATCH 104/118] usb-redir: Try to keep our buffer size near the
Justin M. Forbes d4cdad
 target size
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
Before this patch we would allow the (iso) buffer to grow unlimited
Justin M. Forbes d4cdad
(and it would under certain circumstances) leading to way too high
Justin M. Forbes d4cdad
latencies for iso data streams.
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Justin M. Forbes d4cdad
---
Justin M. Forbes d4cdad
 usb-redir.c |   30 +++++++++++++++++++++++++++---
Justin M. Forbes d4cdad
 1 files changed, 27 insertions(+), 3 deletions(-)
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
diff --git a/usb-redir.c b/usb-redir.c
Justin M. Forbes d4cdad
index 17ea7a7..88d941a 100644
Justin M. Forbes d4cdad
--- a/usb-redir.c
Justin M. Forbes d4cdad
+++ b/usb-redir.c
Justin M. Forbes d4cdad
@@ -61,6 +61,7 @@ struct endp_data {
Justin M. Forbes d4cdad
     uint8_t interrupt_started;
Justin M. Forbes d4cdad
     uint8_t interrupt_error;
Justin M. Forbes d4cdad
     uint8_t bufpq_prefilled;
Justin M. Forbes d4cdad
+    uint8_t bufpq_dropping_packets;
Justin M. Forbes d4cdad
     QTAILQ_HEAD(, buf_packet) bufpq;
Justin M. Forbes d4cdad
     int bufpq_size;
Justin M. Forbes d4cdad
     int bufpq_target_size;
Justin M. Forbes d4cdad
@@ -290,16 +291,34 @@ static void usbredir_cancel_packet(USBDevice *udev, USBPacket *p)
Justin M. Forbes d4cdad
     }
Justin M. Forbes d4cdad
 }
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
-static struct buf_packet *bufp_alloc(USBRedirDevice *dev,
Justin M. Forbes d4cdad
+static void bufp_alloc(USBRedirDevice *dev,
Justin M. Forbes d4cdad
     uint8_t *data, int len, int status, uint8_t ep)
Justin M. Forbes d4cdad
 {
Justin M. Forbes d4cdad
-    struct buf_packet *bufp = g_malloc(sizeof(struct buf_packet));
Justin M. Forbes d4cdad
+    struct buf_packet *bufp;
Justin M. Forbes d4cdad
+
Justin M. Forbes d4cdad
+    if (!dev->endpoint[EP2I(ep)].bufpq_dropping_packets &&
Justin M. Forbes d4cdad
+        dev->endpoint[EP2I(ep)].bufpq_size >
Justin M. Forbes d4cdad
+            2 * dev->endpoint[EP2I(ep)].bufpq_target_size) {
Justin M. Forbes d4cdad
+        DPRINTF("bufpq overflow, dropping packets ep %02X\n", ep);
Justin M. Forbes d4cdad
+        dev->endpoint[EP2I(ep)].bufpq_dropping_packets = 1;
Justin M. Forbes d4cdad
+    }
Justin M. Forbes d4cdad
+    /* Since we're interupting the stream anyways, drop enough packets to get
Justin M. Forbes d4cdad
+       back to our target buffer size */
Justin M. Forbes d4cdad
+    if (dev->endpoint[EP2I(ep)].bufpq_dropping_packets) {
Justin M. Forbes d4cdad
+        if (dev->endpoint[EP2I(ep)].bufpq_size >
Justin M. Forbes d4cdad
+                dev->endpoint[EP2I(ep)].bufpq_target_size) {
Justin M. Forbes d4cdad
+            free(data);
Justin M. Forbes d4cdad
+            return;
Justin M. Forbes d4cdad
+        }
Justin M. Forbes d4cdad
+        dev->endpoint[EP2I(ep)].bufpq_dropping_packets = 0;
Justin M. Forbes d4cdad
+    }
Justin M. Forbes d4cdad
+
Justin M. Forbes d4cdad
+    bufp = g_malloc(sizeof(struct buf_packet));
Justin M. Forbes d4cdad
     bufp->data   = data;
Justin M. Forbes d4cdad
     bufp->len    = len;
Justin M. Forbes d4cdad
     bufp->status = status;
Justin M. Forbes d4cdad
     QTAILQ_INSERT_TAIL(&dev->endpoint[EP2I(ep)].bufpq, bufp, next);
Justin M. Forbes d4cdad
     dev->endpoint[EP2I(ep)].bufpq_size++;
Justin M. Forbes d4cdad
-    return bufp;
Justin M. Forbes d4cdad
 }
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
 static void bufp_free(USBRedirDevice *dev, struct buf_packet *bufp,
Justin M. Forbes d4cdad
@@ -378,6 +397,7 @@ static int usbredir_handle_iso_data(USBRedirDevice *dev, USBPacket *p,
Justin M. Forbes d4cdad
         DPRINTF("iso stream started ep %02X\n", ep);
Justin M. Forbes d4cdad
         dev->endpoint[EP2I(ep)].iso_started = 1;
Justin M. Forbes d4cdad
         dev->endpoint[EP2I(ep)].bufpq_prefilled = 0;
Justin M. Forbes d4cdad
+        dev->endpoint[EP2I(ep)].bufpq_dropping_packets = 0;
Justin M. Forbes d4cdad
     }
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
     if (ep & USB_DIR_IN) {
Justin M. Forbes d4cdad
@@ -504,6 +524,10 @@ static int usbredir_handle_interrupt_data(USBRedirDevice *dev,
Justin M. Forbes d4cdad
             usbredirparser_do_write(dev->parser);
Justin M. Forbes d4cdad
             DPRINTF("interrupt recv started ep %02X\n", ep);
Justin M. Forbes d4cdad
             dev->endpoint[EP2I(ep)].interrupt_started = 1;
Justin M. Forbes d4cdad
+            /* We don't really want to drop interrupt packets ever, but
Justin M. Forbes d4cdad
+               having some upper limit to how much we buffer is good. */
Justin M. Forbes d4cdad
+            dev->endpoint[EP2I(ep)].bufpq_target_size = 1000;
Justin M. Forbes d4cdad
+            dev->endpoint[EP2I(ep)].bufpq_dropping_packets = 0;
Justin M. Forbes d4cdad
         }
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
         intp = QTAILQ_FIRST(&dev->endpoint[EP2I(ep)].bufpq);
Justin M. Forbes d4cdad
-- 
Justin M. Forbes d4cdad
1.7.7.5
Justin M. Forbes d4cdad