Skip to content
  • Hans de Goede's avatar
    usb: Add packet combining functions · a552a966
    Hans de Goede authored
    
    
    Currently we only do pipelining for output endpoints, since to properly
    support short-not-ok semantics we can only have one outstanding input
    packet. Since the ehci and uhci controllers have a limited per td packet
    size guests will split large input transfers to into multiple packets,
    and since we don't pipeline these, this comes with a serious performance
    penalty.
    
    This patch adds helper functions to (re-)combine packets which belong to 1
    transfer at the guest device-driver level into 1 large transger. This can be
    used by (redirection) usb-devices to enable pipelining for input endpoints.
    
    This patch will combine packets together until a transfer terminating packet
    is encountered. A terminating packet is a packet which meets one or more of
    the following conditions:
    1) The packet size is *not* a multiple of the endpoint max packet size
    2) The packet does *not* have its short-not-ok flag set
    3) The packet has its interrupt-on-complete flag set
    
    The short-not-ok flag of the combined packet is that of the terminating packet.
    Multiple combined packets may be submitted to the device, if the combined
    packets do not have their short-not-ok flag set, enabling true pipelining.
    
    If a combined packet does have its short-not-ok flag set the queue will
    wait with submitting further packets to the device until that packet has
    completed.
    
    Once enabled in the usb-redir and ehci code, this improves the speed (MB/s)
    of a Linux guest reading from a USB mass storage device by a factor of
    1.2 - 1.5.
    
    And the main reason why I started working on this, when reading from a pl2303
    USB<->serial converter, it combines the previous 4 packets submitted per
    device-driver level read into 1 big read, reducing the number of packets / sec
    by a factor 4, and it allows to have multiple reads outstanding. This allows
    for much better latency tolerance without the pl2303's internal buffer
    overflowing (which was happening at 115200 bps, without serial flow control).
    
    Signed-off-by: default avatarHans de Goede <hdegoede@redhat.com>
    Signed-off-by: default avatarGerd Hoffmann <kraxel@redhat.com>
    a552a966