Received: by 2002:a05:6a10:6d10:0:0:0:0 with SMTP id gq16csp3659992pxb; Tue, 19 Apr 2022 07:26:49 -0700 (PDT) X-Google-Smtp-Source: ABdhPJySJG2t6tAyM/+EXOuTdMPEJLsob7enhfJAKkTBW8S+d7esu0dTj3bwe5Ka25sm6YwlGMpE X-Received: by 2002:a05:6402:2815:b0:420:c32e:ebe2 with SMTP id h21-20020a056402281500b00420c32eebe2mr17296115ede.1.1650378409098; Tue, 19 Apr 2022 07:26:49 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1650378409; cv=none; d=google.com; s=arc-20160816; b=IYnFfp2VXbKFE2X85ZAdTZaMcYMtTYh6MYWdqpOrf2+/A5kzKWDi4oA5ACCtGck8EZ TjKL/w5amdwZZbH6X63mtdmerFCT8YVU0UDD+PEFvnsdSuozz39mA/xmbWhqOpmL5Agl CXOjPabzCxUtIVrwK8nlAdf+A7G/4K1EkSf8jjUsIGTCocdC/OG3VkQTUNPpF5fCncIR ABZQ+ncKCaEwtF2tmKu5mmi12wZZLYk0RdskjtcQSWKciBdojYwBGM34zUr9EbRR2FZt 3NAaxziKUq7sZ1LZFsQEVJFH5QnRa22LFhX7267qkJmGpcOA7gGzw5Nx+Trd20mExI/q 8dng== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=nG7K1jEqmu2BewBjDqQH/+QXXBFvA+dVovHMwLilx90=; b=rq2KjEansZNaYhI4I9SHzBrjU6u1DMnVF+YraMt+1G/YzYBW4uXuaKbgKcdnDXB+ME GLQg/uyPsc6gmEM9jpBC2LVW3QzKs0UTBI+HKE+/YKO7KhF4NquixqWrSMIv4uZ1PSke hmMTzww51IDvJ2acRQw3j1mn3sl3YLW6qH86XQMj2QNXvGyX1PKwb6XbRWfu+VP8rRfg ZFAEgSRS/lrtwEowwjoa72S6uczjASOdmPt9aF6DQvaMZfhHKEgcYhQgdTDmaOV6tWUg QveLYUKLp8gcDuUm22gWIv9vaaAHmvxrOkc46s+4bRlPOj26Ayb37UdkWt+QyuMOxc0X Chpg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b="J/coWclx"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id c2-20020aa7df02000000b0041cdd61979asi8036504edy.615.2022.04.19.07.26.24; Tue, 19 Apr 2022 07:26:49 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b="J/coWclx"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234616AbiDRM3h (ORCPT + 99 others); Mon, 18 Apr 2022 08:29:37 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37108 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238800AbiDRM03 (ORCPT ); Mon, 18 Apr 2022 08:26:29 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BD5B012636; Mon, 18 Apr 2022 05:20:38 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 5943360F7C; Mon, 18 Apr 2022 12:20:38 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5E8A4C385A1; Mon, 18 Apr 2022 12:20:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1650284437; bh=5ZEo4nk6eol9dr+q6xJOK2Se7Yn1Aa8Wh5aKhVCsr84=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=J/coWclxKotbaoG9lVvq3Ss869pkIuWPTpYg4tMi0BKzycZsF8o38EM42Ww+UstNL 0jy7a65Tgr5sOpyeZdGowYJEFNIquNVv81345SITS4qEajjnGISr/xTMGpqO94B4nT so1HRfeR2sT/lHRR5tSyizeXdt1OqIwK9BJQeM2s= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Takashi Iwai , Sasha Levin Subject: [PATCH 5.17 115/219] ALSA: usb-audio: Limit max buffer and period sizes per time Date: Mon, 18 Apr 2022 14:11:24 +0200 Message-Id: <20220418121210.118991567@linuxfoundation.org> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20220418121203.462784814@linuxfoundation.org> References: <20220418121203.462784814@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-7.7 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_HI, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Takashi Iwai [ Upstream commit 24d0c9f0e7de95fe3e3e0067cbea1cd5d413244b ] In the previous fix, we increased the max buffer bytes from 1MB to 4MB so that we can use bigger buffers for the modern HiFi devices with higher rates, more channels and wider formats. OTOH, extending this has a concern that too big buffer is allowed for the lower rates, less channels and narrower formats; when an application tries to allocate as big buffer as possible, it'll lead to unexpectedly too huge size. Also, we had a problem about the inconsistent max buffer and period bytes for the implicit feedback mode when both streams have different channels. This was fixed by the (relatively complex) patch to reduce the max buffer and period bytes accordingly. This is an alternative fix for those, a patch to kill two birds with one stone (*): instead of increasing the max buffer bytes blindly and applying the reduction per channels, we simply use the hw constraints for the buffer and period "time". Meanwhile the max buffer and period bytes are set unlimited instead. Since the inconsistency of buffer (and period) bytes comes from the difference of the channels in the tied streams, as long as we care only about the buffer (and period) time, it doesn't matter; the buffer time is same for different channels, although we still allow higher buffer size. Similarly, this will allow more buffer bytes for HiFi devices while it also keeps the reasonable size for the legacy devices, too. As of this patch, the max period and buffer time are set to 1 and 2 seconds, which should be large enough for all possible use cases. (*) No animals were harmed in the making of this patch. Fixes: 98c27add5d96 ("ALSA: usb-audio: Cap upper limits of buffer/period bytes for implicit fb") Fixes: fee2ec8cceb3 ("ALSA: usb-audio: Increase max buffer size") Link: https://lore.kernel.org/r/20220412130740.18933-1-tiwai@suse.de Signed-off-by: Takashi Iwai Signed-off-by: Sasha Levin --- sound/usb/pcm.c | 101 +++++++----------------------------------------- 1 file changed, 14 insertions(+), 87 deletions(-) diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c index 37ee6df8b15a..6d699065e81a 100644 --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c @@ -659,9 +659,6 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream) #define hwc_debug(fmt, args...) do { } while(0) #endif -#define MAX_BUFFER_BYTES (4 * 1024 * 1024) -#define MAX_PERIOD_BYTES (512 * 1024) - static const struct snd_pcm_hardware snd_usb_hardware = { .info = SNDRV_PCM_INFO_MMAP | @@ -672,9 +669,9 @@ static const struct snd_pcm_hardware snd_usb_hardware = SNDRV_PCM_INFO_PAUSE, .channels_min = 1, .channels_max = 256, - .buffer_bytes_max = MAX_BUFFER_BYTES, + .buffer_bytes_max = INT_MAX, /* limited by BUFFER_TIME later */ .period_bytes_min = 64, - .period_bytes_max = MAX_PERIOD_BYTES, + .period_bytes_max = INT_MAX, /* limited by PERIOD_TIME later */ .periods_min = 2, .periods_max = 1024, }; @@ -974,78 +971,6 @@ static int hw_rule_periods_implicit_fb(struct snd_pcm_hw_params *params, ep->cur_buffer_periods); } -/* get the adjusted max buffer (or period) bytes that can fit with the - * paired format for implicit fb - */ -static unsigned int -get_adjusted_max_bytes(struct snd_usb_substream *subs, - struct snd_usb_substream *pair, - struct snd_pcm_hw_params *params, - unsigned int max_bytes, - bool reverse_map) -{ - const struct audioformat *fp, *pp; - unsigned int rmax = 0, r; - - list_for_each_entry(fp, &subs->fmt_list, list) { - if (!fp->implicit_fb) - continue; - if (!reverse_map && - !hw_check_valid_format(subs, params, fp)) - continue; - list_for_each_entry(pp, &pair->fmt_list, list) { - if (pp->iface != fp->sync_iface || - pp->altsetting != fp->sync_altsetting || - pp->ep_idx != fp->sync_ep_idx) - continue; - if (reverse_map && - !hw_check_valid_format(pair, params, pp)) - break; - if (!reverse_map && pp->channels > fp->channels) - r = max_bytes * fp->channels / pp->channels; - else if (reverse_map && pp->channels < fp->channels) - r = max_bytes * pp->channels / fp->channels; - else - r = max_bytes; - rmax = max(rmax, r); - break; - } - } - return rmax; -} - -/* Reduce the period or buffer bytes depending on the paired substream; - * when a paired configuration for implicit fb has a higher number of channels, - * we need to reduce the max size accordingly, otherwise it may become unusable - */ -static int hw_rule_bytes_implicit_fb(struct snd_pcm_hw_params *params, - struct snd_pcm_hw_rule *rule) -{ - struct snd_usb_substream *subs = rule->private; - struct snd_usb_substream *pair; - struct snd_interval *it; - unsigned int max_bytes; - unsigned int rmax; - - pair = &subs->stream->substream[!subs->direction]; - if (!pair->ep_num) - return 0; - - if (rule->var == SNDRV_PCM_HW_PARAM_PERIOD_BYTES) - max_bytes = MAX_PERIOD_BYTES; - else - max_bytes = MAX_BUFFER_BYTES; - - rmax = get_adjusted_max_bytes(subs, pair, params, max_bytes, false); - if (!rmax) - rmax = get_adjusted_max_bytes(pair, subs, params, max_bytes, true); - if (!rmax) - return 0; - - it = hw_param_interval(params, rule->var); - return apply_hw_params_minmax(it, 0, rmax); -} - /* * set up the runtime hardware information. */ @@ -1139,6 +1064,18 @@ static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substre return err; } + /* set max period and buffer sizes for 1 and 2 seconds, respectively */ + err = snd_pcm_hw_constraint_minmax(runtime, + SNDRV_PCM_HW_PARAM_PERIOD_TIME, + 0, 1000000); + if (err < 0) + return err; + err = snd_pcm_hw_constraint_minmax(runtime, + SNDRV_PCM_HW_PARAM_BUFFER_TIME, + 0, 2000000); + if (err < 0) + return err; + /* additional hw constraints for implicit fb */ err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_FORMAT, hw_rule_format_implicit_fb, subs, @@ -1160,16 +1097,6 @@ static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substre SNDRV_PCM_HW_PARAM_PERIODS, -1); if (err < 0) return err; - err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, - hw_rule_bytes_implicit_fb, subs, - SNDRV_PCM_HW_PARAM_BUFFER_BYTES, -1); - if (err < 0) - return err; - err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, - hw_rule_bytes_implicit_fb, subs, - SNDRV_PCM_HW_PARAM_PERIOD_BYTES, -1); - if (err < 0) - return err; list_for_each_entry(fp, &subs->fmt_list, list) { if (fp->implicit_fb) { -- 2.35.1