[PATCH 1/3] ALSA USB MIDI: Fix port starvation
Andreas Steinmetz
ast at domdv.de
Mon Mar 16 14:31:15 CET 2020
On Mon, 2020-03-16 at 13:03 +0100, Clemens Ladisch wrote:
> Andreas Steinmetz wrote:
> > the snd_usbmidi_transmit_byte helper had to be converted to
> > return output notification to allow for the 'repeat' shortcut.
>
> Why not simply handle one MIDI byte per port in each iteration? It
> could be argued that single-byte MIDI commands are likely to be real-
> time messages and deserve to go first.
>
Actually the patch does exactly this. As soon as the helper signals
that a message is complete the next port is processed. The "repeat"
loop is just necessary to get a complete class compliant message for
transfer as the helper processes one byte at a time.
The range optimization is there to prevent O(2) performance cost if
possible.
> > Current multi port MIDI interfaces do
> > typically have 2^n output ports and 2^x as wMaxPacketSize where
> > x>n.
>
> The USB specification requires bulk endpoints to have a
> wMaxPacketSize
> value of 8/16/32/64 for full speed, or exactly 512 for high speed.
>
> > For the patch to properly work the wMaxPacketSize of the device
> > must be
> > large enough to allow for at least one MIDI event per port in a
> > URB.
>
> There are devices that handle only the first four bytes of a received
> packet (because Windows used to send only small packets), and one of
> them, the ESI M4U, actually has more than one port.
>
Again no problem as the patch is designed to prefer quirks over user
settings to prevent malfunctioning devices. Quirk processing and thus
size restrictions are processed after user selection.
> My original idea for that FIXME was to use round robin until the
> packet
> is filled (or all ports are empty), and to store the next port index
> (where to start for the next packet) in the endpoint. This would be
> able to distribute the balancing over multiple packets.
>
The problem with "round robin until the packet is filled" is that in
case of a large wMaxPacketSize there's then a huge latency.
I just got for further internal testing an USB3 8x8 interface that uses
a wMaxPacketSize of 512.
In such a case a port doing a sysex transfer will delay another port
then sending a realtime message by a minimum of 123ms per queued URB.
Make that 7 URBs and you have a sysex queue of 860ms until the realtime
message can be transmitted.
>
> Regards,
> Clemens
--
Andreas Steinmetz
More information about the Alsa-devel
mailing list