From patchwork Sat Mar 14 08:11:21 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andreas Steinmetz X-Patchwork-Id: 11438751 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A60166CA for ; Sun, 15 Mar 2020 08:34:42 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 3CE6E20722 for ; Sun, 15 Mar 2020 08:34:42 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=alsa-project.org header.i=@alsa-project.org header.b="lNh2m3i9"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=domdv.de header.i=@domdv.de header.b="N7A2DJXj" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 3CE6E20722 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=domdv.de Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 56DC71871; Sun, 15 Mar 2020 09:33:56 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 56DC71871 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1584261280; bh=kNNS1tzXTwKdeGXskUOrDXYItI9YqzaFmgWLUqd7SFg=; h=Subject:From:To:Date:Cc:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:List-Subscribe:From; b=lNh2m3i90AI2c7X6Kqory3XlCUpDiwoGSaBDqM9QNvW59O40yi4kxYWfPgKOcQjT8 XksBHDm+WiLCGyLa5Df+ez+rFQLzOzcsmtmtzKuB7/etuI4+gK82Y6q8uO+5DV3b/S BXH2G3hLvPvRoHH7W+1LXx7XujXBS8mB+qePs5Co= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 7A2F1F8023E; Sun, 15 Mar 2020 09:33:02 +0100 (CET) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa1.perex.cz (Postfix, from userid 50401) id 1C915F80086; Sat, 14 Mar 2020 09:12:36 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on alsa1.perex.cz X-Spam-Level: X-Spam-Status: No, score=0.2 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,PRX_BODY_65,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=disabled version=3.4.0 Received: from zeus.domdv.de (zeus.domdv.de [IPv6:2a02:2ad0:c00::11]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id B9A27F80086 for ; Sat, 14 Mar 2020 09:12:31 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz B9A27F80086 Authentication-Results: alsa1.perex.cz; dkim=pass (1024-bit key) header.d=domdv.de header.i=@domdv.de header.b="N7A2DJXj" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=domdv.de; s=dk3; h=Content-Transfer-Encoding:MIME-Version:Content-Type:Date:Cc:To:From :Subject:Message-ID:Sender:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: In-Reply-To:References:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=gQp47Lfq/dlfZXdFAAgWsmuiRUI/yH3jDUEAaG1yTuk=; b=N7A2DJXjr0O2E7rSCFdKARDXfC dhp+QE08WIPRmfvxBp9Qh0GgJJoeWA4hSHVocIPxGtcNlIe//Tl97LGA6aCjI88ZbTUqytupSF34U dX0iKyZdJFN4du8FPJpLvRPIdCmfZYrSj5zC6RR5T6zV/3+4TQWo2Rb2EqgIOrRNt5mw=; Received: from [fd06:8443:81a1:74b0::212] (port=1224 helo=castor.lan.domdv.de) by zeus.domdv.de with esmtpsa (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.92.3) (envelope-from ) id 1jD1tC-0001OQ-9y; Sat, 14 Mar 2020 09:11:22 +0100 Received: from woody.lan.domdv.de ([10.1.9.28] helo=host028-server-9.lan.domdv.de) by castor.lan.domdv.de with esmtpsa (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.92.3) (envelope-from ) id 1jD1tC-0003cW-4k; Sat, 14 Mar 2020 09:11:22 +0100 Message-ID: Subject: [PATCH 1/3] ALSA USB MIDI: Fix port starvation From: Andreas Steinmetz To: alsa-devel@alsa-project.org Date: Sat, 14 Mar 2020 09:11:21 +0100 Organization: D.O.M. Datenverarbeitung GmbH User-Agent: Evolution 3.30.5 MIME-Version: 1.0 X-Mailman-Approved-At: Sun, 15 Mar 2020 09:32:59 +0100 Cc: clemens@ladisch.de X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" In case of a multiport USB MIDI interface the lower numbered ports starve higher numbered ports when more than one port is busy transmitting data. The starvation as of the current code is complete and can be for an arbitrarily long time. Control from userspace is not possible without at least halving the theoretically possible device throughput. This is especially bad as there are now 16x16 interface products available. An unpredicable and arbitrarily long latency is not acceptable. The loss of half of the throughput is not acceptable, either. Fair scheduling of all busy ports is required. The patch below balances the actual USB output between all busy ports. It is done in such a way that the single port use performance before applying the patch is identical to the one after applying the patch. To get there, the snd_usbmidi_transmit_byte helper had to be converted to return output notification to allow for the 'repeat' shortcut. The patch tries to avoid O(2) load increase by scaling the balancing loop to the ports that are actually busy as far as this is possible. 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. If this constraint is not met, which is quite improbable, starvation will occur again. Though this could be fixed the likelyhood of such a device is so low that the additional overhead introduced for all other devices is not worth it. Current multi port MIDI interfaces do typically have 2^n output ports and 2^x as wMaxPacketSize where x>n. For a four port USB MIDI interface with a wMaxPacketSize of 64 the maximum latency for any port is changed by the patch from indefinite to 107.52ms. The patch affects the output of all class compliant USB MIDI interfaces. Users will typically experience either no change or increased response, depending on their use case. Signed-off-by: Andreas Steinmetz --- a/sound/usb/midi.c 2020-03-12 22:45:06.611877152 +0100 +++ b/sound/usb/midi.c 2020-03-13 02:33:21.392847930 +0100 @@ -554,7 +554,7 @@ static void snd_usbmidi_output_midiman_p /* * Converts MIDI commands to USB MIDI packets. */ -static void snd_usbmidi_transmit_byte(struct usbmidi_out_port *port, +static int snd_usbmidi_transmit_byte(struct usbmidi_out_port *port, uint8_t b, struct urb *urb) { uint8_t p0 = port->cable; @@ -563,6 +563,7 @@ static void snd_usbmidi_transmit_byte(st if (b >= 0xf8) { output_packet(urb, p0 | 0x0f, b, 0, 0); + return 1; } else if (b >= 0xf0) { switch (b) { case 0xf0: @@ -585,20 +586,20 @@ static void snd_usbmidi_transmit_byte(st case 0xf6: output_packet(urb, p0 | 0x05, 0xf6, 0, 0); port->state = STATE_UNKNOWN; - break; + return 1; case 0xf7: switch (port->state) { case STATE_SYSEX_0: output_packet(urb, p0 | 0x05, 0xf7, 0, 0); - break; + return 1; case STATE_SYSEX_1: output_packet(urb, p0 | 0x06, port->data[0], 0xf7, 0); - break; + return 1; case STATE_SYSEX_2: output_packet(urb, p0 | 0x07, port->data[0], port->data[1], 0xf7); - break; + return 1; } port->state = STATE_UNKNOWN; break; @@ -619,7 +620,7 @@ static void snd_usbmidi_transmit_byte(st port->state = STATE_UNKNOWN; } output_packet(urb, p0, port->data[0], b, 0); - break; + return 1; case STATE_2PARAM_1: port->data[1] = b; port->state = STATE_2PARAM_2; @@ -633,7 +634,7 @@ static void snd_usbmidi_transmit_byte(st port->state = STATE_UNKNOWN; } output_packet(urb, p0, port->data[0], port->data[1], b); - break; + return 1; case STATE_SYSEX_0: port->data[0] = b; port->state = STATE_SYSEX_1; @@ -646,29 +647,49 @@ static void snd_usbmidi_transmit_byte(st output_packet(urb, p0 | 0x04, port->data[0], port->data[1], b); port->state = STATE_SYSEX_0; - break; + return 1; } } + return 0; } static void snd_usbmidi_standard_output(struct snd_usb_midi_out_endpoint *ep, struct urb *urb) { int p; + int start = 0; + int total = 0x10; + int max = ep->max_transfer - 4; + + if (max < 0) + return; + + while (1) { + int first = -1; + int final = -1; - /* FIXME: lower-numbered ports can starve higher-numbered ports */ - for (p = 0; p < 0x10; ++p) { - struct usbmidi_out_port *port = &ep->ports[p]; - if (!port->active) - continue; - while (urb->transfer_buffer_length + 3 < ep->max_transfer) { + for (p = start; p < total; ++p) { + struct usbmidi_out_port *port = &ep->ports[p]; uint8_t b; + if (!port->active) + continue; +repeat: if (snd_rawmidi_transmit(port->substream, &b, 1) != 1) { port->active = 0; - break; + continue; } - snd_usbmidi_transmit_byte(port, b, urb); + if (!snd_usbmidi_transmit_byte(port, b, urb)) + goto repeat; + if (urb->transfer_buffer_length > max) + return; + if (first == -1) + first = p; + final = p; } + if (final == -1) + return; + start = first; + total = final + 1; } } From patchwork Sat Mar 14 08:11:25 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andreas Steinmetz X-Patchwork-Id: 11438753 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 6006E6CA for ; Sun, 15 Mar 2020 08:35:29 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id EB75420737 for ; Sun, 15 Mar 2020 08:35:28 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=alsa-project.org header.i=@alsa-project.org header.b="vM9gHZtl"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=domdv.de header.i=@domdv.de header.b="bFHfCXEr" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org EB75420737 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=domdv.de Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 361D61879; Sun, 15 Mar 2020 09:34:43 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 361D61879 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1584261327; bh=oVnru5yMXHwM6ttGqec4ooXGuyU2MMp8xCGHSGIq4nQ=; h=Subject:From:To:Date:Cc:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:List-Subscribe:From; b=vM9gHZtlKIibv40+t9roPGbq0mGhg39a2FdndUCLMNE2M2/gieyLEPtQjlAw/HXIg 8uwaVxaM1yB3AZWUEOQI12NyrwwsfLfPuU4CQeoq6uBR50n0fRDvWy2gVaMsppzV9u OFMsHA8HkoSKj/cgDd+4+LJKFYukWQQQbr+SuRWM= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 34003F80086; Sun, 15 Mar 2020 09:33:05 +0100 (CET) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa1.perex.cz (Postfix, from userid 50401) id DF95AF8020C; Sat, 14 Mar 2020 09:12:39 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on alsa1.perex.cz X-Spam-Level: X-Spam-Status: No, score=-0.1 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=disabled version=3.4.0 Received: from zeus.domdv.de (zeus.domdv.de [IPv6:2a02:2ad0:c00::11]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 0403EF8013D for ; Sat, 14 Mar 2020 09:12:34 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 0403EF8013D Authentication-Results: alsa1.perex.cz; dkim=pass (1024-bit key) header.d=domdv.de header.i=@domdv.de header.b="bFHfCXEr" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=domdv.de; s=dk3; h=Content-Transfer-Encoding:MIME-Version:Content-Type:Date:Cc:To:From :Subject:Message-ID:Sender:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: In-Reply-To:References:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=BHrLHoS3b9S3egxYoGnr9pRgJAHSWSaim92tfzqxv8k=; b=bFHfCXErZASuEXo6DyPM3JU0/F 8YlYbC7JYZzrY50rLaIzPS2pgm6EQa5qZ+bJ+6khnqOTf5tVo92fpBoBbG8BG4qHNpqEl/3Sm6VaK OtmzPn/zQkDeU8XieI2agKNMjEwnXaFpFK/5/HBiPKjd5piKQQPxW/EE8O2W2Nnw1MlI=; Received: from [fd06:8443:81a1:74b0::212] (port=1226 helo=castor.lan.domdv.de) by zeus.domdv.de with esmtpsa (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.92.3) (envelope-from ) id 1jD1tG-0001Od-0O; Sat, 14 Mar 2020 09:11:26 +0100 Received: from woody.lan.domdv.de ([10.1.9.28] helo=host028-server-9.lan.domdv.de) by castor.lan.domdv.de with esmtpsa (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.92.3) (envelope-from ) id 1jD1tF-0003cb-RN; Sat, 14 Mar 2020 09:11:25 +0100 Message-ID: <4d24ecd833aec61fec3decadf195861c4f22634d.camel@domdv.de> Subject: [PATCH 2/3] ALSA USB MIDI: Make amount of output URBs selectable by user From: Andreas Steinmetz To: alsa-devel@alsa-project.org Date: Sat, 14 Mar 2020 09:11:25 +0100 Organization: D.O.M. Datenverarbeitung GmbH User-Agent: Evolution 3.30.5 MIME-Version: 1.0 X-Mailman-Approved-At: Sun, 15 Mar 2020 09:32:59 +0100 Cc: clemens@ladisch.de X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" This patch introduces a new module parameter "outqueue" which allows userspace to set the amount of output URBs is a range from 1 to 7 with 7 being the default (illegal values are clamped to the next valid value). It is assumed that the previous patch has been applied. Looking then at a multiport USB MIDI interface with a wMaxPacketSize of 64 and assuming an optimal output rate of 320us/byte the following is true: 16 MIDI events PER URB Up to 3 bytes per MIDI event (3 bytes are assumed below) A driver queue of 7 URBs which are completely filled. Resulting latency is 16*3*7*320us=107.52ms So if all URBs are filled by e.g. a sysex transfer on one port, a realtime message delivered by userspace for another port will be delayed by 107.52ms which is far too long. After applying this patch and selecting a queue of only 1 URB tests show that the throughput isn't really affected, the latency however drops to 16*3*1*320us=15.36ms which is considerably better. As the default is not touched no implications are expected for existing users. By making the parameter writable via sysfs it is possible to do selective output URB queue size management from userspace via a script that manages USB authorize and the module option. Signed-off-by: Andreas Steinmetz --- a/sound/usb/midi.c 2020-03-13 19:19:28.614798593 +0100 +++ b/sound/usb/midi.c 2020-03-13 19:37:08.097411436 +0100 @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -77,6 +78,11 @@ MODULE_DESCRIPTION("USB Audio/MIDI helper module"); MODULE_LICENSE("Dual BSD/GPL"); +static int outqueue = OUTPUT_URBS; + +module_param(outqueue, int, 0644); +MODULE_PARM_DESC(outqueue, "Outgoing queue size, 1-7 (default: 7)."); + struct usb_ms_header_descriptor { __u8 bLength; @@ -141,6 +147,7 @@ } urbs[OUTPUT_URBS]; unsigned int active_urbs; unsigned int drain_urbs; + unsigned int out_urbs; int max_transfer; /* size of urb buffer */ struct tasklet_struct tasklet; unsigned int next_urb; @@ -335,7 +342,7 @@ break; ep->active_urbs |= 1 << urb_index; } - if (++urb_index >= OUTPUT_URBS) + if (++urb_index >= ep->out_urbs) urb_index = 0; if (urb_index == ep->next_urb) break; @@ -1364,7 +1371,7 @@ { unsigned int i; - for (i = 0; i < OUTPUT_URBS; ++i) + for (i = 0; i < ep->out_urbs; ++i) if (ep->urbs[i].urb) { free_urb_and_buffer(ep->umidi, ep->urbs[i].urb, ep->max_transfer); @@ -1397,7 +1404,14 @@ return -ENOMEM; ep->umidi = umidi; - for (i = 0; i < OUTPUT_URBS; ++i) { + if (outqueue < 1) + ep->out_urbs = 1; + else if (outqueue > OUTPUT_URBS) + ep->out_urbs = OUTPUT_URBS; + else + ep->out_urbs = outqueue; + + for (i = 0; i < ep->out_urbs; ++i) { ep->urbs[i].urb = usb_alloc_urb(0, GFP_KERNEL); if (!ep->urbs[i].urb) { err = -ENOMEM; @@ -1434,7 +1448,7 @@ ep->max_transfer = 9; break; } - for (i = 0; i < OUTPUT_URBS; ++i) { + for (i = 0; i < ep->out_urbs; ++i) { buffer = usb_alloc_coherent(umidi->dev, ep->max_transfer, GFP_KERNEL, &ep->urbs[i].urb->transfer_dma); @@ -1525,7 +1539,7 @@ if (ep->out) tasklet_kill(&ep->out->tasklet); if (ep->out) { - for (j = 0; j < OUTPUT_URBS; ++j) + for (j = 0; j < ep->out->out_urbs; ++j) usb_kill_urb(ep->out->urbs[j].urb); if (umidi->usb_protocol_ops->finish_out_endpoint) umidi->usb_protocol_ops->finish_out_endpoint(ep->out); From patchwork Sat Mar 14 08:11:28 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andreas Steinmetz X-Patchwork-Id: 11438755 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1D9106CA for ; Sun, 15 Mar 2020 08:36:04 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id A98ED20724 for ; Sun, 15 Mar 2020 08:36:03 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=alsa-project.org header.i=@alsa-project.org header.b="D2MUfUG2"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=domdv.de header.i=@domdv.de header.b="LOg6oevp" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org A98ED20724 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=domdv.de Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id ED1741847; Sun, 15 Mar 2020 09:35:17 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz ED1741847 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1584261362; bh=cI6E34OUlUD5RYYnFmqm4z413wvx8gQIS1EQtokauJY=; h=Subject:From:To:Date:Cc:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:List-Subscribe:From; b=D2MUfUG2UecNP5VB68ps9n6iM0sWHXSAkpA6ThDo0GN2k1P5LkwTFkljKEUKBQwtw sLO/d2f57RfzMbkoS/IVH3SqVtgSZac9S6zkcspvShlf3oc7mOx+dj6csnuAxsJ1+2 x7r5KkGrPWdsnDYJhvAyTcCJjyyYzWVT1f5zH/fQ= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id B7EFFF8028E; Sun, 15 Mar 2020 09:33:07 +0100 (CET) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa1.perex.cz (Postfix, from userid 50401) id 56C0DF801D9; Sat, 14 Mar 2020 09:12:40 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on alsa1.perex.cz X-Spam-Level: X-Spam-Status: No, score=-0.1 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=disabled version=3.4.0 Received: from zeus.domdv.de (zeus.domdv.de [IPv6:2a02:2ad0:c00::11]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 00CD9F80086 for ; Sat, 14 Mar 2020 09:12:36 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 00CD9F80086 Authentication-Results: alsa1.perex.cz; dkim=pass (1024-bit key) header.d=domdv.de header.i=@domdv.de header.b="LOg6oevp" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=domdv.de; s=dk3; h=Content-Transfer-Encoding:MIME-Version:Content-Type:Date:Cc:To:From :Subject:Message-ID:Sender:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: In-Reply-To:References:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=mXhR7kW5ab/f8b7vZ1VJFg3sVuCfHiT6IkAyckcRW9Y=; b=LOg6oevph3guW6mR3UjyFFnUjY zW1aT7Q0l6lZFE47dlS5YWJX587L4pyrL6Qv8rcxgcqvSksC8RfNJrZCekzWTGaKKKXveL2xz56xb oKHrUvWyH3GG+HwDH7vHWwFPLzSp/mdpIWcpMw8GaVWZNPYz7sKYyyal6WanFFCxKUeY=; Received: from [fd06:8443:81a1:74b0::212] (port=1228 helo=castor.lan.domdv.de) by zeus.domdv.de with esmtpsa (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.92.3) (envelope-from ) id 1jD1tJ-0001Oo-14; Sat, 14 Mar 2020 09:11:29 +0100 Received: from woody.lan.domdv.de ([10.1.9.28] helo=host028-server-9.lan.domdv.de) by castor.lan.domdv.de with esmtpsa (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.92.3) (envelope-from ) id 1jD1tI-0003cg-Rm; Sat, 14 Mar 2020 09:11:28 +0100 Message-ID: <00d9b60b04efca71748acb006c05217ec8a28ef8.camel@domdv.de> Subject: [PATCH 3/3] ALSA USB MIDI: Make amount of MIDI events per output URB selectable by user From: Andreas Steinmetz To: alsa-devel@alsa-project.org Date: Sat, 14 Mar 2020 09:11:28 +0100 Organization: D.O.M. Datenverarbeitung GmbH User-Agent: Evolution 3.30.5 MIME-Version: 1.0 X-Mailman-Approved-At: Sun, 15 Mar 2020 09:32:59 +0100 Cc: clemens@ladisch.de X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" This patch introduces a new module parameter "events" which allows userspace to limit the amount of MIDI events per output URB. An "events" value of 0 which is the default means "use wMaxPacketSize". Out of range values for "events" are clamped to the nearest valid value. It is assumed that the previous patches are applied and "outqueue=1" is used. Looking then at a four port USB MIDI interface with a wMaxPacketSize of 64 and assuming an optimal output rate of 320us/byte the following is true: 16 MIDI events PER URB Up to 3 bytes per MIDI event (3 bytes are assumed below) A driver queue of 1 URB which is completely filled. Resulting latency is 16*3*1*320us=15.36ms which still is in the audible range (a latency of less than 5ms is required, think playing a keyboard to MIDI in and using MIDI out to control a piano module and using headphones, while using another port for sysex transfers). After applying this patch and selecting the valid minimum event value of 4 (there must be at least space for one event per port to assert proper output balancing) tests show that the throughput isn't really affected, the worst case latency however drops to 3.84ms which is acceptable. In case of the largest class compliant devices which do have 16 ports the worst case latency is then 15.36ms which is tolerable. If this is still to long it could be fixed by introducing additional complexity to the balancing of snd_usbmidi_standard_output() at some later stage. As the device default is used by default no implications are expected for existing users. By making the parameter writable via sysfs it is possible to do selective output URB event count management from userspace via a script that manages USB authorize and the module option. Signed-off-by: Andreas Steinmetz --- a/sound/usb/midi.c 2020-03-13 20:18:33.443265194 +0100 +++ b/sound/usb/midi.c 2020-03-13 20:42:49.445546326 +0100 @@ -79,9 +79,12 @@ MODULE_LICENSE("Dual BSD/GPL"); static int outqueue = OUTPUT_URBS; +static int events; module_param(outqueue, int, 0644); -MODULE_PARM_DESC(outqueue, "Outgoing queue size, 1-7 (default: 7)."); +MODULE_PARM_DESC(outqueue, "Outgoing MIDI queue size, 1-7 (default: 7)."); +module_param(events, int, 0644); +MODULE_PARM_DESC(events, "MIDI events per queue element, 0=device default (default: 0)."); struct usb_ms_header_descriptor { @@ -1426,6 +1429,17 @@ switch (umidi->usb_id) { default: ep->max_transfer = usb_maxpacket(umidi->dev, pipe, 1); + if (events) { + int ev = 0; + + for (i = 0; i < 0x10; ++i) + if (ep_info->out_cables & (1 << i)) + ev++; + if (events > ev) + ev = events; + if (ev < ep->max_transfer >> 2) + ep->max_transfer = ev << 2; + } break; /* * Various chips declare a packet size larger than 4 bytes, but