From patchwork Thu May 11 12:08:36 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: yixuanjiang X-Patchwork-Id: 13238373 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 42320C7EE22 for ; Thu, 11 May 2023 18:56:25 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 9ECD61EB; Thu, 11 May 2023 20:55:32 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 9ECD61EB DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1683831382; bh=ue6Mr/Vj5dJskGTMSyU+u/1wSbHfp3R/9KXAMP1kIJk=; h=Date:In-Reply-To:References:Subject:From:To:Cc:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=gjemcje+J5oL3hyZsLSHsh8IggZ+h2jbPNrCi268vk5GjdMolePCBU8VNupEsBlDW N3M6FefNJQ02J4XzZjE2ro5aSlddRBGQvkMMpfh0bM30k/lHBs2wduJMJ9bem74epT woNxNxnTrrQqsogUOqhWTiIYKoUCLqgWl9tH+rdM= Received: by alsa1.perex.cz (Postfix, from userid 50401) id F0AD3F80564; Thu, 11 May 2023 20:54:39 +0200 (CEST) Received: from mailman-core.alsa-project.org (mailman-core.alsa-project.org [10.254.200.10]) by alsa1.perex.cz (Postfix) with ESMTP id 6EEF2F80571; Thu, 11 May 2023 20:54:39 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 3AC6AF804B1; Thu, 11 May 2023 14:09:26 +0200 (CEST) Received: from mail-yw1-x1149.google.com (mail-yw1-x1149.google.com [IPv6:2607:f8b0:4864:20::1149]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id BCF16F802E8 for ; Thu, 11 May 2023 14:09:17 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz BCF16F802E8 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key, unprotected) header.d=google.com header.i=@google.com header.a=rsa-sha256 header.s=20221208 header.b=aId7+0de Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-559d8e22306so153963537b3.1 for ; Thu, 11 May 2023 05:09:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1683806955; x=1686398955; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=7K8c0PbSb9/75eHA2UyPAuYfZp6gkS8+sNwMs4nkPsw=; b=aId7+0deecHGhvzHiCpQ99QDZYxs8sOskTVuQh+Id0foMa14spsgvuQ0XA0Z2ZEMuQ XuWIw22ug3J/BYgTc05q7rC0GG7biA1eiBtKmnUHCNLBLOoyslvxzJnEaU8TGLc/hRd0 sGUQCfw0KuMjHnNhKyQGQPxbx5ylmXI1mHuScaYgtPCzlzYAgg2QA2K8IcTSnJbeYsHn zWZH0v/FMPmUTNE0s0iRHoD1v2dG094/NHJ2aH6MshBgjyUU9hs4oLsHhGpBd3ak/fT9 YFhEv6DkZqGYwPRdsNwLA3e+/2qG2HrjBK7ytxtwTYYJjCXevj13Xfhl7vsPsiuoVNIR fELA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1683806955; x=1686398955; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=7K8c0PbSb9/75eHA2UyPAuYfZp6gkS8+sNwMs4nkPsw=; b=GOtL4cYIMFR0jVsB1Joq2J0E5wyIpCwBjxF7ZoCi1xeo/X6O3lDpA/yQvb4JipXmi7 lEUjxm+zzmQ/PrCWtZIBbaLmeUELpAE3faP9vlt5tHb7p1+FHRyfy+R5Ppm/N4eXVbP4 TmRMauUcWiZZ7qkavDBMi195Czr4tidKCUpT+m4n38AyDdIpCLExvbqq5SNW5/kQy8Gl DrZseVRSMXn/JPmV5r2ibG0aGE0mZIwSL/eCnMqfGDzEyfeZt1B7+OQsBzsqdEYBepor FmmykdSMLS5IQZpFlExU8odAoQq76wtrl68px5RTlkwcgQqRNkdlz6yct+2QpL7qfMpc PZ6w== X-Gm-Message-State: AC+VfDyKb4SjyCsl619axYIctOFk8EiIvl7zuKA8FYs1cHuKMrTFdYEA CUK8sybCLQrIdV87wka4KvSdqdBvo1onBGrwQQ== X-Google-Smtp-Source: ACHHUZ649eEZOGu+69lcpa1h2QuufU2JwY+7I6E65DKzbwztYqdOFIXoAXFKOH6AJFiL/OCdeIEENenkhD6EYIzmYA== X-Received: from yixuanjiang.ntc.corp.google.com ([2401:fa00:fc:202:6c9a:64c9:7e44:6b1d]) (user=yixuanjiang job=sendgmr) by 2002:a81:b285:0:b0:559:f1b0:6eb with SMTP id q127-20020a81b285000000b00559f1b006ebmr12820158ywh.4.1683806955346; Thu, 11 May 2023 05:09:15 -0700 (PDT) Date: Thu, 11 May 2023 20:08:36 +0800 In-Reply-To: <20230511120841.2096524-1-yixuanjiang@google.com> Mime-Version: 1.0 References: <20230511120841.2096524-1-yixuanjiang@google.com> X-Mailer: git-send-email 2.40.1.521.gf1e218fcd8-goog Message-ID: <20230511120841.2096524-2-yixuanjiang@google.com> Subject: [PATCH 1/6] ASoC: soc-pcm: use GFP_ATOMIC for dpcm structure From: yixuanjiang To: tiwai@suse.com, lgirdwood@gmail.com, broonie@kernel.org Cc: linux-kernel@vger.kernel.org, alsa-devel@alsa-project.org, Pierre-Louis Bossart , Guennadi Liakhovetski , Kai Vehmanen , Bard Liao , Ranjani Sridharan , Yixuan Jiang , stable@vger.kernel.org X-MailFrom: 369pcZAsKCj43n2zfsonfsllttlqj.htrfqxf-ij0jqfqxf-uwtojhy.twl@flex--yixuanjiang.bounces.google.com X-Mailman-Rule-Hits: nonmember-moderation X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-alsa-devel.alsa-project.org-0; header-match-alsa-devel.alsa-project.org-1 Message-ID-Hash: S23O5KK7HDRGVYA4TA5QIXJ3VAI5UPFE X-Message-ID-Hash: S23O5KK7HDRGVYA4TA5QIXJ3VAI5UPFE X-Mailman-Approved-At: Thu, 11 May 2023 18:54:30 +0000 X-Mailman-Version: 3.3.8 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" Archived-At: List-Archive: <> List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Pierre-Louis Bossart [ Upstream commit d8a9c6e1f6766a16cf02b4e99a629f3c5512c183 ] We allocate a structure in dpcm_be_connect(), which may be called in atomic context. Using GFP_KERNEL is not quite right, we have to use GFP_ATOMIC to prevent the allocator from sleeping. Suggested-by: Guennadi Liakhovetski Signed-off-by: Pierre-Louis Bossart Reviewed-by: Kai Vehmanen Reviewed-by: Bard Liao Reviewed-by: Ranjani Sridharan Link: https://lore.kernel.org/r/20211207173745.15850-2-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown Fixes: aa9ff6a4955f ("ASoC: soc-compress: Reposition and add pcm_mutex") Signed-off-by: Yixuan Jiang Cc: stable@vger.kernel.org # 5.15+ --- sound/soc/soc-pcm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 3b673477f6215..cffae9b7c2548 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -1132,7 +1132,7 @@ static int dpcm_be_connect(struct snd_soc_pcm_runtime *fe, return 0; } - dpcm = kzalloc(sizeof(struct snd_soc_dpcm), GFP_KERNEL); + dpcm = kzalloc(sizeof(struct snd_soc_dpcm), GFP_ATOMIC); if (!dpcm) return -ENOMEM; From patchwork Thu May 11 12:08:37 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: yixuanjiang X-Patchwork-Id: 13238378 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id B6EC7C7EE22 for ; Thu, 11 May 2023 18:57:54 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 7B27BF0; Thu, 11 May 2023 20:57:02 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 7B27BF0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1683831472; bh=DkitLX5tL4D4rIAR1mvc5FQJv/aacb25zLCPOng3ciU=; h=Date:In-Reply-To:References:Subject:From:To:Cc:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=df7lzis2dN1ApET5idHOWLZXr1idqq26EosE/jsRR3Q4EB5UNOhnCxUlg5wdzorvf YTSWqh8/ktKWEMrhaC6TqdA9tUjVFPGmFKY4pkPyJ9gV1chBZ9qC8pKqlbZOAO+m6S qt01TQZDLlc+w1gB94fqzHvqgw7Fecbw5C1/S3cY= Received: by alsa1.perex.cz (Postfix, from userid 50401) id 218EEF805D7; Thu, 11 May 2023 20:54:54 +0200 (CEST) Received: from mailman-core.alsa-project.org (mailman-core.alsa-project.org [10.254.200.10]) by alsa1.perex.cz (Postfix) with ESMTP id B2950F805CA; Thu, 11 May 2023 20:54:53 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id A1315F8032D; Thu, 11 May 2023 14:10:33 +0200 (CEST) Received: from mail-yb1-xb49.google.com (mail-yb1-xb49.google.com [IPv6:2607:f8b0:4864:20::b49]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 69D59F80217 for ; Thu, 11 May 2023 14:09:22 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 69D59F80217 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key, unprotected) header.d=google.com header.i=@google.com header.a=rsa-sha256 header.s=20221208 header.b=Fm3IUSrI Received: by mail-yb1-xb49.google.com with SMTP id 3f1490d57ef6-b9a6f15287eso16715117276.1 for ; Thu, 11 May 2023 05:09:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1683806960; x=1686398960; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=t2dsf61YMVY92FH7C3AkmJ5nwGxSUh4djoxlEJxPoZg=; b=Fm3IUSrIO6dioGkB92APGdJb1osx2Ot5x0wCO0UEqBQxCBUdYRoNP0KTWyt0fb70Z0 0GZSXmqWDxptjteEYn/qpcdE3yJHtilD+khIiE1vi4zw/AqIe479LJ4+t3TRLfs0Hdrv qbcjIG5lSktyPDi9KHlTeqCOUH7pHWTNq5r4ShzUSGY7NaUgc2zZwhMJSkbgwMMxOJSC DqRXkK8qmW3F9pIsE4iFTRoojuExst1QgA6FCVanvZ9KBnCHcCJUbqqcmSE2bqSlddut hxMPdslmmdXESjFTPjiGZ4FC5RgqE65456Ln6uVnae+wXDl01twwgL5I6yU553ow6I9w eCbg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1683806960; x=1686398960; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=t2dsf61YMVY92FH7C3AkmJ5nwGxSUh4djoxlEJxPoZg=; b=Lc2NH7n5zxlcGMWwjBxRLaIihgBRXBujtkJ/ehKr7VjHUJ0AzsHtWwOVyFEzpfZgho TW9yjtuAYdxv0dikvjM8DQEQRlACXMdSObd2XnecDNn4eNsugiNagEE9oz+haam5fWmZ 3anfevIyrS6hurBSjIMoGDM5alcJsyOFNaXFzmttTFUrB9iwJr4H1MXWiXmcoz29Abjx oZn39ZdQMQohRWwTX1EnBJnN/XbPbqdUkOt6PNzXUJpwKkavIonOd7JI63uY/VeATdmi My11AGhFnr4Dx/XGILcNd/8/sbt27yC79zLdNvLmEHu5U86Mb6pLYeQ5UWmXzIScevkP zE6Q== X-Gm-Message-State: AC+VfDzPG46w3Wi4646gBJKm4YoOryOMUuFY+ZxcQjT79pKx8sN8JiCy 7jZRWd1TQYc1Rw9oFFOIF0CUZ02yGjCXqZlNjA== X-Google-Smtp-Source: ACHHUZ6MK+BdZXJuYQp0xdPqOukDcGy3FtdWiMye4msSsyxhUqmlwxjZSZ+VYlg2JzBOa89RPQhW3k2qNI+UA5zS7w== X-Received: from yixuanjiang.ntc.corp.google.com ([2401:fa00:fc:202:6c9a:64c9:7e44:6b1d]) (user=yixuanjiang job=sendgmr) by 2002:a05:6902:d2:b0:b9e:6fce:4f6d with SMTP id i18-20020a05690200d200b00b9e6fce4f6dmr13046837ybs.2.1683806960728; Thu, 11 May 2023 05:09:20 -0700 (PDT) Date: Thu, 11 May 2023 20:08:37 +0800 In-Reply-To: <20230511120841.2096524-1-yixuanjiang@google.com> Mime-Version: 1.0 References: <20230511120841.2096524-1-yixuanjiang@google.com> X-Mailer: git-send-email 2.40.1.521.gf1e218fcd8-goog Message-ID: <20230511120841.2096524-3-yixuanjiang@google.com> Subject: [PATCH 2/6] ASoC: soc-pcm: align BE 'atomicity' with that of the FE From: yixuanjiang To: tiwai@suse.com, lgirdwood@gmail.com, broonie@kernel.org Cc: linux-kernel@vger.kernel.org, alsa-devel@alsa-project.org, Pierre-Louis Bossart , Takashi Iwai , Kai Vehmanen , Bard Liao , Ranjani Sridharan , Yixuan Jiang , stable@vger.kernel.org X-MailFrom: 38NpcZAsKCkM3n2zfsonfsllttlqj.htrfqxf-ij0jqfqxf-uwtojhy.twl@flex--yixuanjiang.bounces.google.com X-Mailman-Rule-Hits: nonmember-moderation X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-alsa-devel.alsa-project.org-0; header-match-alsa-devel.alsa-project.org-1 Message-ID-Hash: YY6IRHZQBLUD624ZFMXJMW3EP6U4WM6Y X-Message-ID-Hash: YY6IRHZQBLUD624ZFMXJMW3EP6U4WM6Y X-Mailman-Approved-At: Thu, 11 May 2023 18:54:31 +0000 X-Mailman-Version: 3.3.8 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Pierre-Louis Bossart [ Upstream commit bbf7d3b1c4f40eb02dd1dffb500ba00b0bff0303 ] Since the flow for DPCM is based on taking a lock for the FE first, we need to make sure during the connection between a BE and an FE that they both use the same 'atomicity', otherwise we may sleep in atomic context. If the FE is nonatomic, this patch forces the BE to be nonatomic as well. That should have no negative impact since the BE 'inherits' the FE properties. However, if the FE is atomic and the BE is not, then the configuration is flagged as invalid. Signed-off-by: Pierre-Louis Bossart [ removed FE stream lock by tiwai ] Signed-off-by: Takashi Iwai Reviewed-by: Kai Vehmanen Reviewed-by: Bard Liao Reviewed-by: Ranjani Sridharan Link: https://lore.kernel.org/r/20211207173745.15850-3-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown Fixes: aa9ff6a4955f ("ASoC: soc-compress: Reposition and add pcm_mutex") Signed-off-by: Yixuan Jiang Cc: stable@vger.kernel.org # 5.15+ --- sound/soc/soc-pcm.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index cffae9b7c2548..373f20bd14301 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -1123,6 +1123,8 @@ static snd_pcm_uframes_t soc_pcm_pointer(struct snd_pcm_substream *substream) static int dpcm_be_connect(struct snd_soc_pcm_runtime *fe, struct snd_soc_pcm_runtime *be, int stream) { + struct snd_pcm_substream *fe_substream; + struct snd_pcm_substream *be_substream; struct snd_soc_dpcm *dpcm; unsigned long flags; @@ -1132,6 +1134,20 @@ static int dpcm_be_connect(struct snd_soc_pcm_runtime *fe, return 0; } + fe_substream = snd_soc_dpcm_get_substream(fe, stream); + be_substream = snd_soc_dpcm_get_substream(be, stream); + + if (!fe_substream->pcm->nonatomic && be_substream->pcm->nonatomic) { + dev_err(be->dev, "%s: FE is atomic but BE is nonatomic, invalid configuration\n", + __func__); + return -EINVAL; + } + if (fe_substream->pcm->nonatomic && !be_substream->pcm->nonatomic) { + dev_warn(be->dev, "%s: FE is nonatomic but BE is not, forcing BE as nonatomic\n", + __func__); + be_substream->pcm->nonatomic = 1; + } + dpcm = kzalloc(sizeof(struct snd_soc_dpcm), GFP_ATOMIC); if (!dpcm) return -ENOMEM; From patchwork Thu May 11 12:08:38 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: yixuanjiang X-Patchwork-Id: 13238374 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id EECC7C77B7C for ; Thu, 11 May 2023 18:56:48 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id D9B7791; Thu, 11 May 2023 20:55:56 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz D9B7791 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1683831406; bh=okQnI0FDin997lxx3qSi9heumRtJ0ZGcgBS8o7cFJzc=; h=Date:In-Reply-To:References:Subject:From:To:Cc:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=lIvyyKZFbAuN3HIh+2dnmTanNH/htiPOMa2HSbsM3HykXQNE4YevsMpu14wvRbRLS Qt7fjHLQNaVtsUu6wq0jxf3AzosTJhpf6/ND6V7OqNVCZ/Fx7oI03cjI/Wxb8WqPpS vygrpvNoqh2tGcwMohjqcxWMZaCPubkN37vVvQfs= Received: by alsa1.perex.cz (Postfix, from userid 50401) id EF1B7F80589; Thu, 11 May 2023 20:54:42 +0200 (CEST) Received: from mailman-core.alsa-project.org (mailman-core.alsa-project.org [10.254.200.10]) by alsa1.perex.cz (Postfix) with ESMTP id 7BAE4F8057B; Thu, 11 May 2023 20:54:42 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id AF1F1F8052E; Thu, 11 May 2023 14:09:37 +0200 (CEST) Received: from mail-yb1-xb49.google.com (mail-yb1-xb49.google.com [IPv6:2607:f8b0:4864:20::b49]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 55CC1F8032D for ; Thu, 11 May 2023 14:09:27 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 55CC1F8032D Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key, unprotected) header.d=google.com header.i=@google.com header.a=rsa-sha256 header.s=20221208 header.b=m+lpwYdA Received: by mail-yb1-xb49.google.com with SMTP id 3f1490d57ef6-b9a6f15287eso16715652276.1 for ; Thu, 11 May 2023 05:09:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1683806967; x=1686398967; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=st4R3zKUH/xDsc4YN+VqInFo/FugaRQOoRBGi61bjqE=; b=m+lpwYdAygmfKOuXS+rQL/1j+qy/4Jz6w5tgYS6IE7Pba0DbUI9SEMsJqPLxgiQmSv DHcJyttCt2F2R2E36BgSM5sBH56vGVofydABwW/EmBIyxn4cW/Oahy1bBHUIREI6+DSg /hTZO1DqOjYEQvTQstR7p+Fs7gycdc2Ps0s1IQXVLp2IP8iqySVFSNNJTC1E+jUSFEnD dQkzy8yX7o3wt4oGzUyFNsBt2ATKu9Bk/T750q27YoO2as2FiLJz1cjtUU/FkHw6s1ZF eOl9Y35rL64M/+9X2qvKk3C+n2bPfAEyHsDdVwOoBAO00l3a66vxlb/sjXpZZ9rYU6vb 6o3A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1683806967; x=1686398967; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=st4R3zKUH/xDsc4YN+VqInFo/FugaRQOoRBGi61bjqE=; b=O6Q8TBFvpU4IVFxhT5b/faz7w4wnUWfJYjNlSGSjmez/9nRaVOdbdTJ/jBV5VvA5gc D1q+fTpbyGUZuc5PlhCcq2iuZwbWfPXcm8kLtPgT0ji07oIgd5ZxyzEz2IANB5PNGSBJ p8ytzItJWMMT/snuhOoi11Y3hl9D6+CCG4hjAWoLahq/nzgFhN244gQPwQC0MSMwM1oC dNcus7TnJWNYNTdPq2Cq8dPQthaWRTLd6c5GEKl0wXnv/j38lRMs9I+fwWYdjHSLYNcu KxhfeI0KAGD8Yx6ktrM0xEcEQrCFE/q3Wiu/LBhhB2zajqpI1ye4GFUliY0gT8slk3YB 2AjA== X-Gm-Message-State: AC+VfDz8W6xlDai7NMS/E9npdeXnaOhzo4ZwaPOJbhJ2aMaY7MoCuTXD MS6CbU2rsGqYw14+8YwfuHEKnwkUDrnEMDGVug== X-Google-Smtp-Source: ACHHUZ49WZh7iQOeS0awLJJmsXs+E42WhPdiu6SF2appFp6ziPx5fny2JHtoWPEWZ19dxRNoHu1piFy54NK2S2VgeQ== X-Received: from yixuanjiang.ntc.corp.google.com ([2401:fa00:fc:202:6c9a:64c9:7e44:6b1d]) (user=yixuanjiang job=sendgmr) by 2002:a25:1283:0:b0:b9a:672d:23c9 with SMTP id 125-20020a251283000000b00b9a672d23c9mr12770147ybs.0.1683806966890; Thu, 11 May 2023 05:09:26 -0700 (PDT) Date: Thu, 11 May 2023 20:08:38 +0800 In-Reply-To: <20230511120841.2096524-1-yixuanjiang@google.com> Mime-Version: 1.0 References: <20230511120841.2096524-1-yixuanjiang@google.com> X-Mailer: git-send-email 2.40.1.521.gf1e218fcd8-goog Message-ID: <20230511120841.2096524-4-yixuanjiang@google.com> Subject: [PATCH 3/6] ASoC: soc-pcm: Fix and cleanup DPCM locking From: yixuanjiang To: tiwai@suse.com, lgirdwood@gmail.com, broonie@kernel.org Cc: linux-kernel@vger.kernel.org, alsa-devel@alsa-project.org, Takashi Iwai , Pierre-Louis Bossart , Kai Vehmanen , Bard Liao , Ranjani Sridharan , Yixuan Jiang , stable@vger.kernel.org X-MailFrom: 39tpcZAsKCkk9t85lyutlyrrzzrwp.nzxlw3l-op6pwlw3l-02zupn4.z2r@flex--yixuanjiang.bounces.google.com X-Mailman-Rule-Hits: nonmember-moderation X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-alsa-devel.alsa-project.org-0; header-match-alsa-devel.alsa-project.org-1 Message-ID-Hash: 4TKH3IHGPXXZL22ANSUU4JNOEQFCHC7G X-Message-ID-Hash: 4TKH3IHGPXXZL22ANSUU4JNOEQFCHC7G X-Mailman-Approved-At: Thu, 11 May 2023 18:54:31 +0000 X-Mailman-Version: 3.3.8 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Takashi Iwai [ Upstream commit b7898396f4bbe160f546d0c5e9fa17cca9a7d153 ] The existing locking for DPCM has several issues a) a confusing mix of card->mutex and card->pcm_mutex. b) a dpcm_lock spinlock added inconsistently and on paths that could be recursively taken. The use of irqsave/irqrestore was also overkill. The suggested model is: 1) The pcm_mutex is the top-most protection of BE links in the FE. The pcm_mutex is applied always on either the top PCM callbacks or the external call from DAPM, not taken in the internal functions. 2) the FE stream lock is taken in higher levels before invoking dpcm_be_dai_trigger() 3) when adding and deleting a BE, both the pcm_mutex and FE stream lock are taken. Signed-off-by: Takashi Iwai [clarification of commit message by plbossart] Signed-off-by: Pierre-Louis Bossart Reviewed-by: Kai Vehmanen Reviewed-by: Bard Liao Reviewed-by: Ranjani Sridharan Link: https://lore.kernel.org/r/20211207173745.15850-4-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown Fixes: aa9ff6a4955f ("ASoC: soc-compress: Reposition and add pcm_mutex") Signed-off-by: Yixuan Jiang Cc: stable@vger.kernel.org # 5.15+ --- include/sound/soc.h | 2 - sound/soc/soc-core.c | 1 - sound/soc/soc-pcm.c | 229 ++++++++++++++++++++++++++++--------------- 3 files changed, 152 insertions(+), 80 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index 0fa0a34582322..c653c5ece68ca 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -907,8 +907,6 @@ struct snd_soc_card { struct mutex pcm_mutex; enum snd_soc_pcm_subclass pcm_subclass; - spinlock_t dpcm_lock; - int (*probe)(struct snd_soc_card *card); int (*late_probe)(struct snd_soc_card *card); int (*remove)(struct snd_soc_card *card); diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index edebb3f50a069..f24e32c765a24 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -2339,7 +2339,6 @@ int snd_soc_register_card(struct snd_soc_card *card) mutex_init(&card->mutex); mutex_init(&card->dapm_mutex); mutex_init(&card->pcm_mutex); - spin_lock_init(&card->dpcm_lock); return snd_soc_bind_card(card); } diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 373f20bd14301..a9869203804e7 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -27,6 +27,31 @@ #include #include +static inline void snd_soc_dpcm_mutex_lock(struct snd_soc_pcm_runtime *rtd) +{ + mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass); +} + +static inline void snd_soc_dpcm_mutex_unlock(struct snd_soc_pcm_runtime *rtd) +{ + mutex_unlock(&rtd->card->pcm_mutex); +} + +#define snd_soc_dpcm_mutex_assert_held(rtd) \ + lockdep_assert_held(&(rtd)->card->pcm_mutex) + +static inline void snd_soc_dpcm_stream_lock_irq(struct snd_soc_pcm_runtime *rtd, + int stream) +{ + snd_pcm_stream_lock_irq(snd_soc_dpcm_get_substream(rtd, stream)); +} + +static inline void snd_soc_dpcm_stream_unlock_irq(struct snd_soc_pcm_runtime *rtd, + int stream) +{ + snd_pcm_stream_unlock_irq(snd_soc_dpcm_get_substream(rtd, stream)); +} + #define DPCM_MAX_BE_USERS 8 static inline const char *soc_cpu_dai_name(struct snd_soc_pcm_runtime *rtd) @@ -73,7 +98,6 @@ static ssize_t dpcm_show_state(struct snd_soc_pcm_runtime *fe, struct snd_pcm_hw_params *params = &fe->dpcm[stream].hw_params; struct snd_soc_dpcm *dpcm; ssize_t offset = 0; - unsigned long flags; /* FE state */ offset += scnprintf(buf + offset, size - offset, @@ -101,7 +125,6 @@ static ssize_t dpcm_show_state(struct snd_soc_pcm_runtime *fe, goto out; } - spin_lock_irqsave(&fe->card->dpcm_lock, flags); for_each_dpcm_be(fe, stream, dpcm) { struct snd_soc_pcm_runtime *be = dpcm->be; params = &dpcm->hw_params; @@ -122,7 +145,6 @@ static ssize_t dpcm_show_state(struct snd_soc_pcm_runtime *fe, params_channels(params), params_rate(params)); } - spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); out: return offset; } @@ -145,11 +167,13 @@ static ssize_t dpcm_state_read_file(struct file *file, char __user *user_buf, if (!buf) return -ENOMEM; + snd_soc_dpcm_mutex_lock(fe); for_each_pcm_streams(stream) if (snd_soc_dai_stream_valid(asoc_rtd_to_cpu(fe, 0), stream)) offset += dpcm_show_state(fe, stream, buf + offset, out_count - offset); + snd_soc_dpcm_mutex_unlock(fe); ret = simple_read_from_buffer(user_buf, count, ppos, buf, offset); @@ -221,14 +245,14 @@ static void dpcm_set_fe_update_state(struct snd_soc_pcm_runtime *fe, struct snd_pcm_substream *substream = snd_soc_dpcm_get_substream(fe, stream); - snd_pcm_stream_lock_irq(substream); + snd_soc_dpcm_stream_lock_irq(fe, stream); if (state == SND_SOC_DPCM_UPDATE_NO && fe->dpcm[stream].trigger_pending) { dpcm_fe_dai_do_trigger(substream, fe->dpcm[stream].trigger_pending - 1); fe->dpcm[stream].trigger_pending = 0; } fe->dpcm[stream].runtime_update = state; - snd_pcm_stream_unlock_irq(substream); + snd_soc_dpcm_stream_unlock_irq(fe, stream); } static void dpcm_set_be_update_state(struct snd_soc_pcm_runtime *be, @@ -256,7 +280,7 @@ void snd_soc_runtime_action(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai; int i; - lockdep_assert_held(&rtd->card->pcm_mutex); + snd_soc_dpcm_mutex_assert_held(rtd); for_each_rtd_dais(rtd, i, dai) snd_soc_dai_action(dai, stream, action); @@ -309,6 +333,8 @@ int dpcm_dapm_stream_event(struct snd_soc_pcm_runtime *fe, int dir, { struct snd_soc_dpcm *dpcm; + snd_soc_dpcm_mutex_assert_held(fe); + for_each_dpcm_be(fe, dir, dpcm) { struct snd_soc_pcm_runtime *be = dpcm->be; @@ -646,14 +672,14 @@ static int soc_pcm_components_close(struct snd_pcm_substream *substream, return ret; } -static int soc_pcm_clean(struct snd_pcm_substream *substream, int rollback) +static int soc_pcm_clean(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_substream *substream, int rollback) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); struct snd_soc_component *component; struct snd_soc_dai *dai; int i; - mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass); + snd_soc_dpcm_mutex_assert_held(rtd); if (!rollback) snd_soc_runtime_deactivate(rtd, substream->stream); @@ -665,9 +691,6 @@ static int soc_pcm_clean(struct snd_pcm_substream *substream, int rollback) soc_pcm_components_close(substream, rollback); - - mutex_unlock(&rtd->card->pcm_mutex); - snd_soc_pcm_component_pm_runtime_put(rtd, substream, rollback); for_each_rtd_components(rtd, i, component) @@ -682,9 +705,21 @@ static int soc_pcm_clean(struct snd_pcm_substream *substream, int rollback) * freed here. The cpu DAI, codec DAI, machine and components are also * shutdown. */ +static int __soc_pcm_close(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_substream *substream) +{ + return soc_pcm_clean(rtd, substream, 0); +} + +/* PCM close ops for non-DPCM streams */ static int soc_pcm_close(struct snd_pcm_substream *substream) { - return soc_pcm_clean(substream, 0); + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + + snd_soc_dpcm_mutex_lock(rtd); + soc_pcm_clean(rtd, substream, 0); + snd_soc_dpcm_mutex_unlock(rtd); + return 0; } static int soc_hw_sanity_check(struct snd_pcm_substream *substream) @@ -730,21 +765,21 @@ static int soc_hw_sanity_check(struct snd_pcm_substream *substream) * then initialized and any private data can be allocated. This also calls * startup for the cpu DAI, component, machine and codec DAI. */ -static int soc_pcm_open(struct snd_pcm_substream *substream) +static int __soc_pcm_open(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_substream *substream) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); struct snd_soc_component *component; struct snd_soc_dai *dai; int i, ret = 0; + snd_soc_dpcm_mutex_assert_held(rtd); + for_each_rtd_components(rtd, i, component) pinctrl_pm_select_default_state(component->dev); ret = snd_soc_pcm_component_pm_runtime_get(rtd, substream); if (ret < 0) - goto pm_err; - - mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass); + goto err; ret = soc_pcm_components_open(substream); if (ret < 0) @@ -786,16 +821,26 @@ static int soc_pcm_open(struct snd_pcm_substream *substream) snd_soc_runtime_activate(rtd, substream->stream); ret = 0; err: - mutex_unlock(&rtd->card->pcm_mutex); -pm_err: if (ret < 0) { - soc_pcm_clean(substream, 1); + soc_pcm_clean(rtd, substream, 1); dev_err(rtd->dev, "%s() failed (%d)", __func__, ret); } return ret; } +/* PCM open ops for non-DPCM streams */ +static int soc_pcm_open(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + int ret; + + snd_soc_dpcm_mutex_lock(rtd); + ret = __soc_pcm_open(rtd, substream); + snd_soc_dpcm_mutex_unlock(rtd); + return ret; +} + static void codec2codec_close_delayed_work(struct snd_soc_pcm_runtime *rtd) { /* @@ -811,13 +856,13 @@ static void codec2codec_close_delayed_work(struct snd_soc_pcm_runtime *rtd) * rate, etc. This function is non atomic and can be called multiple times, * it can refer to the runtime info. */ -static int soc_pcm_prepare(struct snd_pcm_substream *substream) +static int __soc_pcm_prepare(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_substream *substream) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); struct snd_soc_dai *dai; int i, ret = 0; - mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass); + snd_soc_dpcm_mutex_assert_held(rtd); ret = snd_soc_link_prepare(substream); if (ret < 0) @@ -845,14 +890,24 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream) snd_soc_dai_digital_mute(dai, 0, substream->stream); out: - mutex_unlock(&rtd->card->pcm_mutex); - if (ret < 0) dev_err(rtd->dev, "ASoC: %s() failed (%d)\n", __func__, ret); return ret; } +/* PCM prepare ops for non-DPCM streams */ +static int soc_pcm_prepare(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + int ret; + + snd_soc_dpcm_mutex_lock(rtd); + ret = __soc_pcm_prepare(rtd, substream); + snd_soc_dpcm_mutex_unlock(rtd); + return ret; +} + static void soc_pcm_codec_params_fixup(struct snd_pcm_hw_params *params, unsigned int mask) { @@ -864,13 +919,13 @@ static void soc_pcm_codec_params_fixup(struct snd_pcm_hw_params *params, interval->max = channels; } -static int soc_pcm_hw_clean(struct snd_pcm_substream *substream, int rollback) +static int soc_pcm_hw_clean(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_substream *substream, int rollback) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); struct snd_soc_dai *dai; int i; - mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass); + snd_soc_dpcm_mutex_assert_held(rtd); /* clear the corresponding DAIs parameters when going to be inactive */ for_each_rtd_dais(rtd, i, dai) { @@ -900,16 +955,28 @@ static int soc_pcm_hw_clean(struct snd_pcm_substream *substream, int rollback) snd_soc_dai_hw_free(dai, substream, rollback); } - mutex_unlock(&rtd->card->pcm_mutex); return 0; } /* * Frees resources allocated by hw_params, can be called multiple times */ +static int __soc_pcm_hw_free(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_substream *substream) +{ + return soc_pcm_hw_clean(rtd, substream, 0); +} + +/* hw_free PCM ops for non-DPCM streams */ static int soc_pcm_hw_free(struct snd_pcm_substream *substream) { - return soc_pcm_hw_clean(substream, 0); + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + int ret; + + snd_soc_dpcm_mutex_lock(rtd); + ret = __soc_pcm_hw_free(rtd, substream); + snd_soc_dpcm_mutex_unlock(rtd); + return ret; } /* @@ -917,15 +984,15 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream) * function can also be called multiple times and can allocate buffers * (using snd_pcm_lib_* ). It's non-atomic. */ -static int soc_pcm_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) +static int __soc_pcm_hw_params(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); struct snd_soc_dai *cpu_dai; struct snd_soc_dai *codec_dai; int i, ret = 0; - mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass); + snd_soc_dpcm_mutex_assert_held(rtd); ret = soc_pcm_params_symmetry(substream, params); if (ret) @@ -997,16 +1064,27 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream, ret = snd_soc_pcm_component_hw_params(substream, params); out: - mutex_unlock(&rtd->card->pcm_mutex); - if (ret < 0) { - soc_pcm_hw_clean(substream, 1); + soc_pcm_hw_clean(rtd, substream, 1); dev_err(rtd->dev, "ASoC: %s() failed (%d)\n", __func__, ret); } return ret; } +/* hw_params PCM ops for non-DPCM streams */ +static int soc_pcm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + int ret; + + snd_soc_dpcm_mutex_lock(rtd); + ret = __soc_pcm_hw_params(rtd, substream, params); + snd_soc_dpcm_mutex_unlock(rtd); + return ret; +} + static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd) { struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); @@ -1126,7 +1204,8 @@ static int dpcm_be_connect(struct snd_soc_pcm_runtime *fe, struct snd_pcm_substream *fe_substream; struct snd_pcm_substream *be_substream; struct snd_soc_dpcm *dpcm; - unsigned long flags; + + snd_soc_dpcm_mutex_assert_held(fe); /* only add new dpcms */ for_each_dpcm_be(fe, stream, dpcm) { @@ -1156,10 +1235,10 @@ static int dpcm_be_connect(struct snd_soc_pcm_runtime *fe, dpcm->fe = fe; be->dpcm[stream].runtime = fe->dpcm[stream].runtime; dpcm->state = SND_SOC_DPCM_LINK_STATE_NEW; - spin_lock_irqsave(&fe->card->dpcm_lock, flags); + snd_soc_dpcm_stream_lock_irq(fe, stream); list_add(&dpcm->list_be, &fe->dpcm[stream].be_clients); list_add(&dpcm->list_fe, &be->dpcm[stream].fe_clients); - spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); + snd_soc_dpcm_stream_unlock_irq(fe, stream); dev_dbg(fe->dev, "connected new DPCM %s path %s %s %s\n", stream ? "capture" : "playback", fe->dai_link->name, @@ -1204,8 +1283,10 @@ static void dpcm_be_reparent(struct snd_soc_pcm_runtime *fe, void dpcm_be_disconnect(struct snd_soc_pcm_runtime *fe, int stream) { struct snd_soc_dpcm *dpcm, *d; - unsigned long flags; + snd_soc_dpcm_mutex_assert_held(fe); + + snd_soc_dpcm_stream_lock_irq(fe, stream); for_each_dpcm_be_safe(fe, stream, dpcm, d) { dev_dbg(fe->dev, "ASoC: BE %s disconnect check for %s\n", stream ? "capture" : "playback", @@ -1223,12 +1304,11 @@ void dpcm_be_disconnect(struct snd_soc_pcm_runtime *fe, int stream) dpcm_remove_debugfs_state(dpcm); - spin_lock_irqsave(&fe->card->dpcm_lock, flags); list_del(&dpcm->list_be); list_del(&dpcm->list_fe); - spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); kfree(dpcm); } + snd_soc_dpcm_stream_unlock_irq(fe, stream); } /* get BE for DAI widget and stream */ @@ -1442,12 +1522,9 @@ int dpcm_process_paths(struct snd_soc_pcm_runtime *fe, void dpcm_clear_pending_state(struct snd_soc_pcm_runtime *fe, int stream) { struct snd_soc_dpcm *dpcm; - unsigned long flags; - spin_lock_irqsave(&fe->card->dpcm_lock, flags); for_each_dpcm_be(fe, stream, dpcm) dpcm_set_be_update_state(dpcm->be, stream, SND_SOC_DPCM_UPDATE_NO); - spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); } void dpcm_be_dai_stop(struct snd_soc_pcm_runtime *fe, int stream, @@ -1483,12 +1560,12 @@ void dpcm_be_dai_stop(struct snd_soc_pcm_runtime *fe, int stream, continue; if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_FREE) { - soc_pcm_hw_free(be_substream); + __soc_pcm_hw_free(be, be_substream); be->dpcm[stream].state = SND_SOC_DPCM_STATE_HW_FREE; } } - soc_pcm_close(be_substream); + __soc_pcm_close(be, be_substream); be_substream->runtime = NULL; be->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE; } @@ -1536,7 +1613,7 @@ int dpcm_be_dai_startup(struct snd_soc_pcm_runtime *fe, int stream) stream ? "capture" : "playback", be->dai_link->name); be_substream->runtime = be->dpcm[stream].runtime; - err = soc_pcm_open(be_substream); + err = __soc_pcm_open(be, be_substream); if (err < 0) { be->dpcm[stream].users--; if (be->dpcm[stream].users < 0) @@ -1780,7 +1857,7 @@ static int dpcm_fe_dai_startup(struct snd_pcm_substream *fe_substream) dev_dbg(fe->dev, "ASoC: open FE %s\n", fe->dai_link->name); /* start the DAI frontend */ - ret = soc_pcm_open(fe_substream); + ret = __soc_pcm_open(fe, fe_substream); if (ret < 0) goto unwind; @@ -1811,6 +1888,8 @@ static int dpcm_fe_dai_shutdown(struct snd_pcm_substream *substream) struct snd_soc_pcm_runtime *fe = asoc_substream_to_rtd(substream); int stream = substream->stream; + snd_soc_dpcm_mutex_assert_held(fe); + dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_FE); /* shutdown the BEs */ @@ -1819,7 +1898,7 @@ static int dpcm_fe_dai_shutdown(struct snd_pcm_substream *substream) dev_dbg(fe->dev, "ASoC: close FE %s\n", fe->dai_link->name); /* now shutdown the frontend */ - soc_pcm_close(substream); + __soc_pcm_close(fe, substream); /* run the stream stop event */ dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_STOP); @@ -1864,7 +1943,7 @@ void dpcm_be_dai_hw_free(struct snd_soc_pcm_runtime *fe, int stream) dev_dbg(be->dev, "ASoC: hw_free BE %s\n", be->dai_link->name); - soc_pcm_hw_free(be_substream); + __soc_pcm_hw_free(be, be_substream); be->dpcm[stream].state = SND_SOC_DPCM_STATE_HW_FREE; } @@ -1875,13 +1954,13 @@ static int dpcm_fe_dai_hw_free(struct snd_pcm_substream *substream) struct snd_soc_pcm_runtime *fe = asoc_substream_to_rtd(substream); int stream = substream->stream; - mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME); + snd_soc_dpcm_mutex_lock(fe); dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_FE); dev_dbg(fe->dev, "ASoC: hw_free FE %s\n", fe->dai_link->name); /* call hw_free on the frontend */ - soc_pcm_hw_free(substream); + soc_pcm_hw_clean(fe, substream, 0); /* only hw_params backends that are either sinks or sources * to this frontend DAI */ @@ -1890,7 +1969,7 @@ static int dpcm_fe_dai_hw_free(struct snd_pcm_substream *substream) fe->dpcm[stream].state = SND_SOC_DPCM_STATE_HW_FREE; dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_NO); - mutex_unlock(&fe->card->mutex); + snd_soc_dpcm_mutex_unlock(fe); return 0; } @@ -1934,7 +2013,7 @@ int dpcm_be_dai_hw_params(struct snd_soc_pcm_runtime *fe, int stream) dev_dbg(be->dev, "ASoC: hw_params BE %s\n", be->dai_link->name); - ret = soc_pcm_hw_params(be_substream, &dpcm->hw_params); + ret = __soc_pcm_hw_params(be, be_substream, &dpcm->hw_params); if (ret < 0) goto unwind; @@ -1964,7 +2043,7 @@ int dpcm_be_dai_hw_params(struct snd_soc_pcm_runtime *fe, int stream) (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP)) continue; - soc_pcm_hw_free(be_substream); + __soc_pcm_hw_free(be, be_substream); } return ret; @@ -1976,7 +2055,7 @@ static int dpcm_fe_dai_hw_params(struct snd_pcm_substream *substream, struct snd_soc_pcm_runtime *fe = asoc_substream_to_rtd(substream); int ret, stream = substream->stream; - mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME); + snd_soc_dpcm_mutex_lock(fe); dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_FE); memcpy(&fe->dpcm[stream].hw_params, params, @@ -1990,7 +2069,7 @@ static int dpcm_fe_dai_hw_params(struct snd_pcm_substream *substream, params_channels(params), params_format(params)); /* call hw_params on the frontend */ - ret = soc_pcm_hw_params(substream, params); + ret = __soc_pcm_hw_params(fe, substream, params); if (ret < 0) dpcm_be_dai_hw_free(fe, stream); else @@ -1998,7 +2077,7 @@ static int dpcm_fe_dai_hw_params(struct snd_pcm_substream *substream, out: dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_NO); - mutex_unlock(&fe->card->mutex); + snd_soc_dpcm_mutex_unlock(fe); if (ret < 0) dev_err(fe->dev, "ASoC: %s failed (%d)\n", __func__, ret); @@ -2269,7 +2348,7 @@ int dpcm_be_dai_prepare(struct snd_soc_pcm_runtime *fe, int stream) dev_dbg(be->dev, "ASoC: prepare BE %s\n", be->dai_link->name); - ret = soc_pcm_prepare(be_substream); + ret = __soc_pcm_prepare(be, be_substream); if (ret < 0) break; @@ -2287,7 +2366,7 @@ static int dpcm_fe_dai_prepare(struct snd_pcm_substream *substream) struct snd_soc_pcm_runtime *fe = asoc_substream_to_rtd(substream); int stream = substream->stream, ret = 0; - mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME); + snd_soc_dpcm_mutex_lock(fe); dev_dbg(fe->dev, "ASoC: prepare FE %s\n", fe->dai_link->name); @@ -2306,7 +2385,7 @@ static int dpcm_fe_dai_prepare(struct snd_pcm_substream *substream) goto out; /* call prepare on the frontend */ - ret = soc_pcm_prepare(substream); + ret = __soc_pcm_prepare(fe, substream); if (ret < 0) goto out; @@ -2314,7 +2393,7 @@ static int dpcm_fe_dai_prepare(struct snd_pcm_substream *substream) out: dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_NO); - mutex_unlock(&fe->card->mutex); + snd_soc_dpcm_mutex_unlock(fe); if (ret < 0) dev_err(fe->dev, "ASoC: %s() failed (%d)\n", __func__, ret); @@ -2365,7 +2444,6 @@ static int dpcm_run_update_startup(struct snd_soc_pcm_runtime *fe, int stream) struct snd_soc_dpcm *dpcm; enum snd_soc_dpcm_trigger trigger = fe->dai_link->trigger[stream]; int ret = 0; - unsigned long flags; dev_dbg(fe->dev, "ASoC: runtime %s open on FE %s\n", stream ? "capture" : "playback", fe->dai_link->name); @@ -2434,7 +2512,6 @@ static int dpcm_run_update_startup(struct snd_soc_pcm_runtime *fe, int stream) dpcm_be_dai_shutdown(fe, stream); disconnect: /* disconnect any pending BEs */ - spin_lock_irqsave(&fe->card->dpcm_lock, flags); for_each_dpcm_be(fe, stream, dpcm) { struct snd_soc_pcm_runtime *be = dpcm->be; @@ -2446,7 +2523,6 @@ static int dpcm_run_update_startup(struct snd_soc_pcm_runtime *fe, int stream) be->dpcm[stream].state == SND_SOC_DPCM_STATE_NEW) dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE; } - spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); if (ret < 0) dev_err(fe->dev, "ASoC: %s() failed (%d)\n", __func__, ret); @@ -2521,7 +2597,7 @@ int snd_soc_dpcm_runtime_update(struct snd_soc_card *card) struct snd_soc_pcm_runtime *fe; int ret = 0; - mutex_lock_nested(&card->mutex, SND_SOC_CARD_CLASS_RUNTIME); + mutex_lock_nested(&card->pcm_mutex, card->pcm_subclass); /* shutdown all old paths first */ for_each_card_rtds(card, fe) { ret = soc_dpcm_fe_runtime_update(fe, 0); @@ -2537,7 +2613,7 @@ int snd_soc_dpcm_runtime_update(struct snd_soc_card *card) } out: - mutex_unlock(&card->mutex); + mutex_unlock(&card->pcm_mutex); return ret; } EXPORT_SYMBOL_GPL(snd_soc_dpcm_runtime_update); @@ -2548,6 +2624,8 @@ static void dpcm_fe_dai_cleanup(struct snd_pcm_substream *fe_substream) struct snd_soc_dpcm *dpcm; int stream = fe_substream->stream; + snd_soc_dpcm_mutex_assert_held(fe); + /* mark FE's links ready to prune */ for_each_dpcm_be(fe, stream, dpcm) dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE; @@ -2562,12 +2640,12 @@ static int dpcm_fe_dai_close(struct snd_pcm_substream *fe_substream) struct snd_soc_pcm_runtime *fe = asoc_substream_to_rtd(fe_substream); int ret; - mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME); + snd_soc_dpcm_mutex_lock(fe); ret = dpcm_fe_dai_shutdown(fe_substream); dpcm_fe_dai_cleanup(fe_substream); - mutex_unlock(&fe->card->mutex); + snd_soc_dpcm_mutex_unlock(fe); return ret; } @@ -2578,7 +2656,7 @@ static int dpcm_fe_dai_open(struct snd_pcm_substream *fe_substream) int ret; int stream = fe_substream->stream; - mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME); + snd_soc_dpcm_mutex_lock(fe); fe->dpcm[stream].runtime = fe_substream->runtime; ret = dpcm_path_get(fe, stream, &list); @@ -2595,7 +2673,7 @@ static int dpcm_fe_dai_open(struct snd_pcm_substream *fe_substream) dpcm_clear_pending_state(fe, stream); dpcm_path_put(&list); open_end: - mutex_unlock(&fe->card->mutex); + snd_soc_dpcm_mutex_unlock(fe); return ret; } @@ -2856,10 +2934,8 @@ static int snd_soc_dpcm_check_state(struct snd_soc_pcm_runtime *fe, struct snd_soc_dpcm *dpcm; int state; int ret = 1; - unsigned long flags; int i; - spin_lock_irqsave(&fe->card->dpcm_lock, flags); for_each_dpcm_fe(be, stream, dpcm) { if (dpcm->fe == fe) @@ -2873,7 +2949,6 @@ static int snd_soc_dpcm_check_state(struct snd_soc_pcm_runtime *fe, } } } - spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); /* it's safe to do this BE DAI */ return ret; From patchwork Thu May 11 12:08:39 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: yixuanjiang X-Patchwork-Id: 13238375 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id BCEB2C7EE24 for ; Thu, 11 May 2023 18:57:08 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id EA1501D7; Thu, 11 May 2023 20:56:11 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz EA1501D7 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1683831422; bh=EroXMyzHnX4tZOJiUk1hYJJlCrPuOibWbu2YpDsHLcs=; h=Date:In-Reply-To:References:Subject:From:To:Cc:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=cX+ovh/+avxc9cQY5MhPu2Til9VIixgHDthW0j3bXK/YXlOAcw3h7qGcFCxyAr56f +ghTDUKNVzAQvcP57T54TpaD1M4GOC9aE4UjuNQgstRc79c/9GmJ41UswwC4LOAtWH 1sY4UAgdyz7fqz3LCbwTN/2itqX4bb09WcDen6Vo= Received: by alsa1.perex.cz (Postfix, from userid 50401) id C8CE7F805AE; Thu, 11 May 2023 20:54:46 +0200 (CEST) Received: from mailman-core.alsa-project.org (mailman-core.alsa-project.org [10.254.200.10]) by alsa1.perex.cz (Postfix) with ESMTP id 63487F805AA; Thu, 11 May 2023 20:54:46 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 8BD40F8052E; Thu, 11 May 2023 14:09:40 +0200 (CEST) Received: from mail-yb1-xb4a.google.com (mail-yb1-xb4a.google.com [IPv6:2607:f8b0:4864:20::b4a]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 9AC54F802E8 for ; Thu, 11 May 2023 14:09:34 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 9AC54F802E8 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key, unprotected) header.d=google.com header.i=@google.com header.a=rsa-sha256 header.s=20221208 header.b=FTjyNd5o Received: by mail-yb1-xb4a.google.com with SMTP id 3f1490d57ef6-b8f46dc51bdso18505493276.3 for ; Thu, 11 May 2023 05:09:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1683806973; x=1686398973; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=XPzNid5gFkEdV46hZfBaNY8C9ibiypdAE09EY9qCMiM=; b=FTjyNd5o/ZPhnqTxuIjaMOuIKr0bPgqlmCD27VEg29Us81kFdgS2chf/kuRZIkHZnR 08fY6oknRR4XT12Jco+PYRooLlFiUwKKiDZRCBQC2rAHvImaGCUvDb/jzYXiy10iKLPp 9maFIN+7EJu7YMvS+No4g4fx4Pg209K8NmepG8w1hKOFhT5TeV0/Fsyckne13qVsFN5K EYwhUX1k14BJtWLDQPam0cwZ6XyDsEy9JPXHiFeuxJzMWQnzAC5fLU2Dp0RYKmlkaexj OJrfAl4riB1rBcINA7deGx3JWhU4bkPk+77tRV+dr5AbxqZcoO/fVBjuFXo16hc/2ByL 64VQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1683806973; x=1686398973; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=XPzNid5gFkEdV46hZfBaNY8C9ibiypdAE09EY9qCMiM=; b=SRHKDKg5GMo47i/fVUZfBsR+0F4UnPgLBZlKDX6o+InqCRkmKXMOa0tmRQm6k0VDY+ wv7gH9A8SWPpzxMG8gHBv87b+83UHjsLDzy0jNHS3xB4m38NARqPMVtXS45K3ehZ8Pk5 /XqTEIrV2ZlwX8weTQsInnDvjU1beZdGBWDyIh6LQq/JUEP2lYDug50gsPXO6P4jLpbP D74+VE3BS98MZRceeMXd9saiQcGb7X/77fyLHB8wa/RvfdDjZxD7MoM7OkJo/6ij8TXp SzF1lg2E2MLJoi/oUcONex2r033bXd51J8jiTxVGRymInazKXWBqAynoFpgE/VjWqDPY +sKw== X-Gm-Message-State: AC+VfDydNeLRVPbQOTuHxVoQmLnXd1dElYaV/NnI/YlQoclvK5E0TYrH didQp6Qfskd2XrRJkaKA3wzcPuPPmkCSefgvxg== X-Google-Smtp-Source: ACHHUZ5M7lalg3R0OTBFOw7aw1K392RqKR/D3Vgq7TGontZQbwpIRCkOfvqz8tsJVMK07+Y0NDyGiuFN0IO3Ir5NIw== X-Received: from yixuanjiang.ntc.corp.google.com ([2401:fa00:fc:202:6c9a:64c9:7e44:6b1d]) (user=yixuanjiang job=sendgmr) by 2002:a25:6542:0:b0:b95:4128:bff6 with SMTP id z63-20020a256542000000b00b954128bff6mr12771743ybb.1.1683806972993; Thu, 11 May 2023 05:09:32 -0700 (PDT) Date: Thu, 11 May 2023 20:08:39 +0800 In-Reply-To: <20230511120841.2096524-1-yixuanjiang@google.com> Mime-Version: 1.0 References: <20230511120841.2096524-1-yixuanjiang@google.com> X-Mailer: git-send-email 2.40.1.521.gf1e218fcd8-goog Message-ID: <20230511120841.2096524-5-yixuanjiang@google.com> Subject: [PATCH 4/6] ASoC: soc-pcm: serialize BE triggers From: yixuanjiang To: tiwai@suse.com, lgirdwood@gmail.com, broonie@kernel.org Cc: linux-kernel@vger.kernel.org, alsa-devel@alsa-project.org, Takashi Iwai , Pierre-Louis Bossart , Kai Vehmanen , Bard Liao , Ranjani Sridharan , Yixuan Jiang , stable@vger.kernel.org X-MailFrom: 3_NpcZAsKCk8FzEBr40zr4xx55x2v.t53r29r-uvCv2r29r-6850vtA.58x@flex--yixuanjiang.bounces.google.com X-Mailman-Rule-Hits: nonmember-moderation X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-alsa-devel.alsa-project.org-0; header-match-alsa-devel.alsa-project.org-1 Message-ID-Hash: 4HGVB2NXNTYWZCZJDPWHAMW5ZBGMFE35 X-Message-ID-Hash: 4HGVB2NXNTYWZCZJDPWHAMW5ZBGMFE35 X-Mailman-Approved-At: Thu, 11 May 2023 18:54:31 +0000 X-Mailman-Version: 3.3.8 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Takashi Iwai [ Upstream commit b2ae80663008a7662febe7d13f14ea1b2eb0cd51 ] When more than one FE is connected to a BE, e.g. in a mixing use case, the BE can be triggered multiple times when the FE are opened/started concurrently. This race condition is problematic in the case of SoundWire BE dailinks, and this is not desirable in a general case. This patch relies on the existing BE PCM lock, which takes atomicity into account. The locking model assumes that all interactions start with the FE, so that there is no deadlock between FE and BE locks. Signed-off-by: Takashi Iwai [test, checkpatch fix and clarification of commit message by plbossart] Signed-off-by: Pierre-Louis Bossart Reviewed-by: Kai Vehmanen Reviewed-by: Bard Liao Reviewed-by: Ranjani Sridharan Link: https://lore.kernel.org/r/20211207173745.15850-5-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown Fixes: aa9ff6a4955f ("ASoC: soc-compress: Reposition and add pcm_mutex") Signed-off-by: Yixuan Jiang Cc: stable@vger.kernel.org # 5.15+ --- sound/soc/soc-pcm.c | 46 ++++++++++++++++++++++++++++----------------- 1 file changed, 29 insertions(+), 17 deletions(-) diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index a9869203804e7..7903516c89a6a 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -46,12 +46,18 @@ static inline void snd_soc_dpcm_stream_lock_irq(struct snd_soc_pcm_runtime *rtd, snd_pcm_stream_lock_irq(snd_soc_dpcm_get_substream(rtd, stream)); } +#define snd_soc_dpcm_stream_lock_irqsave(rtd, stream, flags) \ + snd_pcm_stream_lock_irqsave(snd_soc_dpcm_get_substream(rtd, stream), flags) + static inline void snd_soc_dpcm_stream_unlock_irq(struct snd_soc_pcm_runtime *rtd, int stream) { snd_pcm_stream_unlock_irq(snd_soc_dpcm_get_substream(rtd, stream)); } +#define snd_soc_dpcm_stream_unlock_irqrestore(rtd, stream, flags) \ + snd_pcm_stream_unlock_irqrestore(snd_soc_dpcm_get_substream(rtd, stream), flags) + #define DPCM_MAX_BE_USERS 8 static inline const char *soc_cpu_dai_name(struct snd_soc_pcm_runtime *rtd) @@ -2090,6 +2096,7 @@ int dpcm_be_dai_trigger(struct snd_soc_pcm_runtime *fe, int stream, { struct snd_soc_pcm_runtime *be; struct snd_soc_dpcm *dpcm; + unsigned long flags; int ret = 0; for_each_dpcm_be(fe, stream, dpcm) { @@ -2098,9 +2105,11 @@ int dpcm_be_dai_trigger(struct snd_soc_pcm_runtime *fe, int stream, be = dpcm->be; be_substream = snd_soc_dpcm_get_substream(be, stream); + snd_soc_dpcm_stream_lock_irqsave(be, stream, flags); + /* is this op for this BE ? */ if (!snd_soc_dpcm_be_can_update(fe, be, stream)) - continue; + goto next; dev_dbg(be->dev, "ASoC: trigger BE %s cmd %d\n", be->dai_link->name, cmd); @@ -2110,77 +2119,80 @@ int dpcm_be_dai_trigger(struct snd_soc_pcm_runtime *fe, int stream, if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_PREPARE) && (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP) && (be->dpcm[stream].state != SND_SOC_DPCM_STATE_PAUSED)) - continue; + goto next; ret = soc_pcm_trigger(be_substream, cmd); if (ret) - goto end; + goto next; be->dpcm[stream].state = SND_SOC_DPCM_STATE_START; break; case SNDRV_PCM_TRIGGER_RESUME: if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_SUSPEND)) - continue; + goto next; ret = soc_pcm_trigger(be_substream, cmd); if (ret) - goto end; + goto next; be->dpcm[stream].state = SND_SOC_DPCM_STATE_START; break; case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_PAUSED)) - continue; + goto next; ret = soc_pcm_trigger(be_substream, cmd); if (ret) - goto end; + goto next; be->dpcm[stream].state = SND_SOC_DPCM_STATE_START; break; case SNDRV_PCM_TRIGGER_STOP: if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_START) && (be->dpcm[stream].state != SND_SOC_DPCM_STATE_PAUSED)) - continue; + goto next; if (!snd_soc_dpcm_can_be_free_stop(fe, be, stream)) - continue; + goto next; ret = soc_pcm_trigger(be_substream, cmd); if (ret) - goto end; + goto next; be->dpcm[stream].state = SND_SOC_DPCM_STATE_STOP; break; case SNDRV_PCM_TRIGGER_SUSPEND: if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_START) - continue; + goto next; if (!snd_soc_dpcm_can_be_free_stop(fe, be, stream)) - continue; + goto next; ret = soc_pcm_trigger(be_substream, cmd); if (ret) - goto end; + goto next; be->dpcm[stream].state = SND_SOC_DPCM_STATE_SUSPEND; break; case SNDRV_PCM_TRIGGER_PAUSE_PUSH: if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_START) - continue; + goto next; if (!snd_soc_dpcm_can_be_free_stop(fe, be, stream)) - continue; + goto next; ret = soc_pcm_trigger(be_substream, cmd); if (ret) - goto end; + goto next; be->dpcm[stream].state = SND_SOC_DPCM_STATE_PAUSED; break; } +next: + snd_soc_dpcm_stream_unlock_irqrestore(be, stream, flags); + if (ret) + break; } -end: if (ret < 0) dev_err(fe->dev, "ASoC: %s() failed at %s (%d)\n", __func__, be->dai_link->name, ret); From patchwork Thu May 11 12:08:40 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: yixuanjiang X-Patchwork-Id: 13238376 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id A1703C7EE24 for ; Thu, 11 May 2023 18:57:15 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 19C1C209; Thu, 11 May 2023 20:56:23 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 19C1C209 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1683831433; bh=8diD/Bq41b082OkUMdzNXdgnkNpYeOgsXf5A+TRXZqo=; h=Date:In-Reply-To:References:Subject:From:To:Cc:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=sJjV7NkimheRdx/1nG+mcYFgpIjexA9KoN7tT389Zjv0Y3Ajr8lwqXiZ9U35FpSiI K1Qrm+IN4vuyfKYwGvoEwDf1kC4/X48eFW4Sa31L0qnttWYSTxu852LM5+4I8oAdhn XqLFzAmO/1gHvX+r2ATShR8y+kWwzDPwmnipwMXU= Received: by alsa1.perex.cz (Postfix, from userid 50401) id 3BF6CF805B4; Thu, 11 May 2023 20:54:49 +0200 (CEST) Received: from mailman-core.alsa-project.org (mailman-core.alsa-project.org [10.254.200.10]) by alsa1.perex.cz (Postfix) with ESMTP id C10DDF805AC; Thu, 11 May 2023 20:54:48 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id B9774F8053B; Thu, 11 May 2023 14:09:42 +0200 (CEST) Received: from mail-yb1-xb4a.google.com (mail-yb1-xb4a.google.com [IPv6:2607:f8b0:4864:20::b4a]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id A9F45F80310 for ; Thu, 11 May 2023 14:09:40 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz A9F45F80310 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key, unprotected) header.d=google.com header.i=@google.com header.a=rsa-sha256 header.s=20221208 header.b=s+ibXT5L Received: by mail-yb1-xb4a.google.com with SMTP id 3f1490d57ef6-ba1b052e540so16489360276.3 for ; Thu, 11 May 2023 05:09:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1683806979; x=1686398979; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=Gq50IKagmAfx+KtR1kRor/KE8cLkJvCa6loH1PRIiT0=; b=s+ibXT5LhfW0Hyd5StfD45uuSAvx2H35hDpVPqOWumUSnfgb134dW44DYQTgLH6880 Qb+kPoclvkP8Wre0VOySezhrld8bbiXeYV3QHpnqVstEYYfOZWqS5aJI/EpjJ6SZXfOY b9QWDFOt5zwBAxzL/I9XAM4IQSRsuPaW09RG0Zad4Mf8ek2BRVFrEcoymoKGP8wp1fk9 ImAAH6jR/E/s7O8CutcWKEMY/XG3HYzhvmU0gvEvSg9/rUe546yR4t45/mKklroGj6HA jPcIK5VNpzuyNey3AuoxcAgvbMYlb18wc6gUpAO2AkbX+4bXGxiWaRd+BAkn+LnYoQln Cwug== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1683806979; x=1686398979; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=Gq50IKagmAfx+KtR1kRor/KE8cLkJvCa6loH1PRIiT0=; b=NBhrHF3FfwKMATAx2zE+NRHljHVsyI4frmaY7O9PP/cz3qu5H4p4XfkZt9LGvhug6h GgJhVbaLmF6H8psarmqZAupQdIzAPU8L321rDD+6L2F4yiJYB9ajf0H15TjJgJjCXXBY OSNFcV/fWd6H8PNVnyWLr7mZEhoarBqWVwwawSSZM8FCzix5dyQAzh+9RhdEQZz02PgR saS32CdWVtki7pFKSfMlSMo/aY5nERT1p69cbjeIFDOmvpGzZ159V/vzstok1whDw14T 0+Z2ysvZdP3HV2xDxgZyapux1fxUV8icPmoEqAWnT6Gfn0wwZNRG4aNiGLR17jAkG48M zbRw== X-Gm-Message-State: AC+VfDy502DQzuRbeRv6CQ8P2nABnrKE8r5xyRND9DCBAgopmyc3Z0le xQg/dSHZnVdGqkesM9cpO/gIyI4+BxJUDf9SYQ== X-Google-Smtp-Source: ACHHUZ7GXRvobpmjcTV1wtH42bsAR8OSXx4rcv3iFvcVWxwI4sZT6AufYn5/awPTYWKCyvVEL5XHKRiPeMfsWd2itA== X-Received: from yixuanjiang.ntc.corp.google.com ([2401:fa00:fc:202:6c9a:64c9:7e44:6b1d]) (user=yixuanjiang job=sendgmr) by 2002:a25:abb0:0:b0:b9e:71a7:3bc9 with SMTP id v45-20020a25abb0000000b00b9e71a73bc9mr12788020ybi.10.1683806978838; Thu, 11 May 2023 05:09:38 -0700 (PDT) Date: Thu, 11 May 2023 20:08:40 +0800 In-Reply-To: <20230511120841.2096524-1-yixuanjiang@google.com> Mime-Version: 1.0 References: <20230511120841.2096524-1-yixuanjiang@google.com> X-Mailer: git-send-email 2.40.1.521.gf1e218fcd8-goog Message-ID: <20230511120841.2096524-6-yixuanjiang@google.com> Subject: [PATCH 5/6] ASoC: soc-pcm: test refcount before triggering From: yixuanjiang To: tiwai@suse.com, lgirdwood@gmail.com, broonie@kernel.org Cc: linux-kernel@vger.kernel.org, alsa-devel@alsa-project.org, Pierre-Louis Bossart , Kai Vehmanen , Bard Liao , Ranjani Sridharan , Yixuan Jiang , stable@vger.kernel.org X-MailFrom: 3AttcZAsKClUL5KHxA65xA33BB381.zB9x8Fx-01I18x8Fx-CEB61zG.BE3@flex--yixuanjiang.bounces.google.com X-Mailman-Rule-Hits: nonmember-moderation X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-alsa-devel.alsa-project.org-0; header-match-alsa-devel.alsa-project.org-1 Message-ID-Hash: BY2LCNY22QCLR3ETFDMVKYNKRB7LLL7R X-Message-ID-Hash: BY2LCNY22QCLR3ETFDMVKYNKRB7LLL7R X-Mailman-Approved-At: Thu, 11 May 2023 18:54:31 +0000 X-Mailman-Version: 3.3.8 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" Archived-At: <> List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Pierre-Louis Bossart [ Upstream commit 848aedfdc6ba25ad5652797db9266007773e44dd ] On start/pause_release/resume, when more than one FE is connected to the same BE, it's possible that the trigger is sent more than once. This is not desirable, we only want to trigger a BE once, which is straightforward to implement with a refcount. For stop/pause/suspend, the problem is more complicated: the check implemented in snd_soc_dpcm_can_be_free_stop() may fail due to a conceptual deadlock when we trigger the BE before the FE. In this case, the FE states have not yet changed, so there are corner cases where the TRIGGER_STOP is never sent - the dual case of start where multiple triggers might be sent. This patch suggests an unconditional trigger in all cases, without checking the FE states, using a refcount protected by the BE PCM stream lock. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Kai Vehmanen Reviewed-by: Bard Liao Reviewed-by: Ranjani Sridharan Link: https://lore.kernel.org/r/20211207173745.15850-6-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown Fixes: aa9ff6a4955f ("ASoC: soc-compress: Reposition and add pcm_mutex") Signed-off-by: Yixuan Jiang Cc: stable@vger.kernel.org # 5.15+ --- include/sound/soc-dpcm.h | 2 ++ sound/soc/soc-pcm.c | 53 +++++++++++++++++++++++++++++++--------- 2 files changed, 44 insertions(+), 11 deletions(-) diff --git a/include/sound/soc-dpcm.h b/include/sound/soc-dpcm.h index e296a3949b18b..d963f3b608489 100644 --- a/include/sound/soc-dpcm.h +++ b/include/sound/soc-dpcm.h @@ -101,6 +101,8 @@ struct snd_soc_dpcm_runtime { enum snd_soc_dpcm_state state; int trigger_pending; /* trigger cmd + 1 if pending, 0 if not */ + + int be_start; /* refcount protected by BE stream pcm lock */ }; #define for_each_dpcm_fe(be, stream, _dpcm) \ diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 7903516c89a6a..b6099d36518f5 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -1630,7 +1630,7 @@ int dpcm_be_dai_startup(struct snd_soc_pcm_runtime *fe, int stream) be->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE; goto unwind; } - + be->dpcm[stream].be_start = 0; be->dpcm[stream].state = SND_SOC_DPCM_STATE_OPEN; count++; } @@ -2116,14 +2116,21 @@ int dpcm_be_dai_trigger(struct snd_soc_pcm_runtime *fe, int stream, switch (cmd) { case SNDRV_PCM_TRIGGER_START: - if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_PREPARE) && + if (!be->dpcm[stream].be_start && + (be->dpcm[stream].state != SND_SOC_DPCM_STATE_PREPARE) && (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP) && (be->dpcm[stream].state != SND_SOC_DPCM_STATE_PAUSED)) goto next; + be->dpcm[stream].be_start++; + if (be->dpcm[stream].be_start != 1) + goto next; + ret = soc_pcm_trigger(be_substream, cmd); - if (ret) + if (ret) { + be->dpcm[stream].be_start--; goto next; + } be->dpcm[stream].state = SND_SOC_DPCM_STATE_START; break; @@ -2131,9 +2138,15 @@ int dpcm_be_dai_trigger(struct snd_soc_pcm_runtime *fe, int stream, if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_SUSPEND)) goto next; + be->dpcm[stream].be_start++; + if (be->dpcm[stream].be_start != 1) + goto next; + ret = soc_pcm_trigger(be_substream, cmd); - if (ret) + if (ret) { + be->dpcm[stream].be_start--; goto next; + } be->dpcm[stream].state = SND_SOC_DPCM_STATE_START; break; @@ -2141,9 +2154,15 @@ int dpcm_be_dai_trigger(struct snd_soc_pcm_runtime *fe, int stream, if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_PAUSED)) goto next; + be->dpcm[stream].be_start++; + if (be->dpcm[stream].be_start != 1) + goto next; + ret = soc_pcm_trigger(be_substream, cmd); - if (ret) + if (ret) { + be->dpcm[stream].be_start--; goto next; + } be->dpcm[stream].state = SND_SOC_DPCM_STATE_START; break; @@ -2152,12 +2171,18 @@ int dpcm_be_dai_trigger(struct snd_soc_pcm_runtime *fe, int stream, (be->dpcm[stream].state != SND_SOC_DPCM_STATE_PAUSED)) goto next; - if (!snd_soc_dpcm_can_be_free_stop(fe, be, stream)) + if (be->dpcm[stream].state == SND_SOC_DPCM_STATE_START) + be->dpcm[stream].be_start--; + + if (be->dpcm[stream].be_start != 0) goto next; ret = soc_pcm_trigger(be_substream, cmd); - if (ret) + if (ret) { + if (be->dpcm[stream].state == SND_SOC_DPCM_STATE_START) + be->dpcm[stream].be_start++; goto next; + } be->dpcm[stream].state = SND_SOC_DPCM_STATE_STOP; break; @@ -2165,12 +2190,15 @@ int dpcm_be_dai_trigger(struct snd_soc_pcm_runtime *fe, int stream, if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_START) goto next; - if (!snd_soc_dpcm_can_be_free_stop(fe, be, stream)) + be->dpcm[stream].be_start--; + if (be->dpcm[stream].be_start != 0) goto next; ret = soc_pcm_trigger(be_substream, cmd); - if (ret) + if (ret) { + be->dpcm[stream].be_start++; goto next; + } be->dpcm[stream].state = SND_SOC_DPCM_STATE_SUSPEND; break; @@ -2178,12 +2206,15 @@ int dpcm_be_dai_trigger(struct snd_soc_pcm_runtime *fe, int stream, if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_START) goto next; - if (!snd_soc_dpcm_can_be_free_stop(fe, be, stream)) + be->dpcm[stream].be_start--; + if (be->dpcm[stream].be_start != 0) goto next; ret = soc_pcm_trigger(be_substream, cmd); - if (ret) + if (ret) { + be->dpcm[stream].be_start++; goto next; + } be->dpcm[stream].state = SND_SOC_DPCM_STATE_PAUSED; break; From patchwork Thu May 11 12:08:41 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: yixuanjiang X-Patchwork-Id: 13238377 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id EB28DC77B7C for ; Thu, 11 May 2023 18:57:35 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id BF41B1E8; Thu, 11 May 2023 20:56:43 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz BF41B1E8 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1683831453; bh=zfCHa7i9QyCFbh1cpkUjXaCW+hOJFm5MW/4bdohqefo=; h=Date:In-Reply-To:References:Subject:From:To:Cc:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=TrVQ3oENIjyMerregndN8Wr4D10pr7Ro1u/oPKTvivVFMepnG1/sPuf7hOTW2OKYd ynpVWuqDKkFmf2ci9vZYqbAinDQwmE5vVaE5YsXgLvSUlZ9t0tHfMh7MKAuE3I/+8W bm/y73nuOqdeVEfc3WayeCkOLAJv++wHftp6lH6Y= Received: by alsa1.perex.cz (Postfix, from userid 50401) id 6ECF6F805C8; Thu, 11 May 2023 20:54:51 +0200 (CEST) Received: from mailman-core.alsa-project.org (mailman-core.alsa-project.org [10.254.200.10]) by alsa1.perex.cz (Postfix) with ESMTP id A50B2F805C5; Thu, 11 May 2023 20:54:50 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 41008F804B1; Thu, 11 May 2023 14:09:53 +0200 (CEST) Received: from mail-yb1-xb49.google.com (mail-yb1-xb49.google.com [IPv6:2607:f8b0:4864:20::b49]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 49006F80310 for ; Thu, 11 May 2023 14:09:51 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 49006F80310 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key, unprotected) header.d=google.com header.i=@google.com header.a=rsa-sha256 header.s=20221208 header.b=wS6sSkP9 Received: by mail-yb1-xb49.google.com with SMTP id 3f1490d57ef6-ba2d0b391d3so10603807276.2 for ; Thu, 11 May 2023 05:09:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1683806984; x=1686398984; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=DFFdKRwDpDILumhyLuLJOTrk05DbXLc6wTGy62C/3Mw=; b=wS6sSkP9YPrEQci5WRw3K0xUtOK5+0/bwAebx2k91pqCIj0EfYjinxZrDO4ajIZjGM 93t//KRpj0A5F6J4KjOlKV1y+Lm/ePEWG+KQn/cR4aakq3zES0kTJ5K9FNJ38y837AN0 zBdhJGmHaQva80CE20d2I7pxXjrPjUcICIIMWKC+WwF8uB15gtNLv/4ImBvcL36KXmeB lqIS0virSRAaqSbuFnvycK3dKd0Kl7oqzEVb5PehKYMtdlLdGF42nsRcfsVhiU5qg+8j RWNR0gNjin97dZ3upG8fYJP+RPue2YJLbFd3/VCnCJqCjLsUh1T1O2t+pQCpgrkHV8vM z1/g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1683806984; x=1686398984; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=DFFdKRwDpDILumhyLuLJOTrk05DbXLc6wTGy62C/3Mw=; b=FrIb21e6J/Kp8fyEaLNENzYu4f+DbIcRAcYWL9FJ/9euaMOzP4vtfiIMIafCCRYOMJ GjkPxjOFV0p1PDzIEul+c7IvFgMyBfzDm1FFMBXo+iEsw58hZetxEd08KtCMMsvfmoRJ x0M770AYjWl43O23h1B2456wtGOTM6aAR7+ddGMWuELv85zzGliJTV/IPIIs/ON9tex5 6WblA52O2yYSncstPSIunF89sIBD6hvr+Mo/SJ4p84/VJFaQP5Uf8u0LKqfqZa2ZNYuj j/cDKwtk4znnGWjKHZXAm/jC/0Jf1q0t9H/I32O9eqZoygAenWyKPa5POk/zsOyQgtob Gyaw== X-Gm-Message-State: AC+VfDw061Nc8AmyTgs/wG5X4oCFEXYfL5sF4CI3IurEcArX/2vkoMai y8RczjirceOCVrDFm3ph7Omj7N6fMRZ0gN964w== X-Google-Smtp-Source: ACHHUZ6WNFGb++Bi1s3+Qljz7xPC8nDjrsTQIYeDWQxaajEyJ9TDJ4kJ1ngdN74pybDKr5utVuVJdeHDE4xVvgjKyw== X-Received: from yixuanjiang.ntc.corp.google.com ([2401:fa00:fc:202:6c9a:64c9:7e44:6b1d]) (user=yixuanjiang job=sendgmr) by 2002:a25:6648:0:b0:b68:7a4a:5258 with SMTP id z8-20020a256648000000b00b687a4a5258mr12799183ybm.3.1683806984600; Thu, 11 May 2023 05:09:44 -0700 (PDT) Date: Thu, 11 May 2023 20:08:41 +0800 In-Reply-To: <20230511120841.2096524-1-yixuanjiang@google.com> Mime-Version: 1.0 References: <20230511120841.2096524-1-yixuanjiang@google.com> X-Mailer: git-send-email 2.40.1.521.gf1e218fcd8-goog Message-ID: <20230511120841.2096524-7-yixuanjiang@google.com> Subject: [PATCH 6/6] ASoC: soc-pcm: fix BE handling of PAUSE_RELEASE From: yixuanjiang To: tiwai@suse.com, lgirdwood@gmail.com, broonie@kernel.org Cc: linux-kernel@vger.kernel.org, alsa-devel@alsa-project.org, Pierre-Louis Bossart , Bard Liao , Kai Vehmanen , Bard Liao , Ranjani Sridharan , Yixuan Jiang , stable@vger.kernel.org X-MailFrom: 3CNtcZAsKClsRBQN3GCB3G99HH9E7.5HF3EL3-67O7E3EL3-IKHC75M.HK9@flex--yixuanjiang.bounces.google.com X-Mailman-Rule-Hits: nonmember-moderation X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-alsa-devel.alsa-project.org-0; header-match-alsa-devel.alsa-project.org-1 Message-ID-Hash: 2HSLSXGWJY3PQQXW77N6ZHAQU4RXI7YC X-Message-ID-Hash: 2HSLSXGWJY3PQQXW77N6ZHAQU4RXI7YC X-Mailman-Approved-At: Thu, 11 May 2023 18:54:31 +0000 X-Mailman-Version: 3.3.8 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Pierre-Louis Bossart [ Upstream commit 3aa1e96a2b95e2ece198f8dd01e96818971b84df ] A BE connected to more than one FE, e.g. in a mixer case, can go through the following transitions. play FE1 -> BE state is START pause FE1 -> BE state is PAUSED play FE2 -> BE state is START stop FE2 -> BE state is STOP (see note [1] below) release FE1 -> BE state is START stop FE1 -> BE state is STOP play FE1 -> BE state is START pause FE1 -> BE state is PAUSED play FE2 -> BE state is START release FE1 -> BE state is START stop FE2 -> BE state is START stop FE1 -> BE state is STOP play FE1 -> BE state is START play FE2 -> BE state is START (no change) pause FE1 -> BE state is START (no change) pause FE2 -> BE state is PAUSED release FE1 -> BE state is START release FE2 -> BE state is START (no change) stop FE1 -> BE state is START (no change) stop FE2 -> BE state is STOP The existing code for PAUSE_RELEASE only allows for the case where the BE is paused, which clearly would not work in the sequences above. Extend the allowed states to restart the BE when PAUSE_RELEASE is received, and increase the refcount if the BE is already in START. [1] the existing logic does not move the BE state back to PAUSED when the FE2 is stopped. This patch does not change the logic; it would be painful to keep a history of changes on the FE side, the state machine is already rather complicated with transitions based on the last BE state and the trigger type. Reported-by: Bard Liao Signed-off-by: Pierre-Louis Bossart Reviewed-by: Kai Vehmanen Reviewed-by: Bard Liao Reviewed-by: Ranjani Sridharan Link: https://lore.kernel.org/r/20211207173745.15850-7-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown Fixes: aa9ff6a4955f ("ASoC: soc-compress: Reposition and add pcm_mutex") Signed-off-by: Yixuan Jiang Cc: stable@vger.kernel.org # 5.15+ --- sound/soc/soc-pcm.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index b6099d36518f5..6e589708b9338 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -2151,7 +2151,10 @@ int dpcm_be_dai_trigger(struct snd_soc_pcm_runtime *fe, int stream, be->dpcm[stream].state = SND_SOC_DPCM_STATE_START; break; case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_PAUSED)) + if (!be->dpcm[stream].be_start && + (be->dpcm[stream].state != SND_SOC_DPCM_STATE_START) && + (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP) && + (be->dpcm[stream].state != SND_SOC_DPCM_STATE_PAUSED)) goto next; be->dpcm[stream].be_start++;