Received: by 2002:a05:6358:9144:b0:117:f937:c515 with SMTP id r4csp8724918rwr; Thu, 11 May 2023 05:33:47 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ6qdg+SkDXoEHU9qXJF/VWEh4oQGlrzW3kBHmoauxCU0K4+R2Odd/4iMI3Zw6hCbAd6kuhS X-Received: by 2002:a05:6a20:7d96:b0:f6:592a:7e3d with SMTP id v22-20020a056a207d9600b000f6592a7e3dmr25230263pzj.7.1683808426608; Thu, 11 May 2023 05:33:46 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1683808426; cv=none; d=google.com; s=arc-20160816; b=ZsnNhgjZcfq4ZGDGVI2HjIuXwO53GMqgilC8MVTiLpYQZqMr8Z81Fp5UAXBMHYSl2E jhlF1wvU3DQi3TEKmwAGL02qZirgaVdDDTE9rtf9+6leIfmzOdhz2hXYkc+Hq3v9Ib2r MH9FL7ntI8qeb6PHKovnEvg8+OFgut8/wsFcqljEq8dfalFuoX8EdmUz6/eDFfP0VJx/ z9RnAgKeZ9/UfWWW9hDijl6JqJYwhFNoFRSQoGwB0D7GI37/l8k/UZ01I7dMQedgbydU 42eOwqmtP1plAIFlABbO/2fHQPHRLsD/XL1QJIGySVC+H0hcTomwe6KVdbgqJDhu6m30 cayA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:from:subject:message-id:references :mime-version:in-reply-to:date:dkim-signature; bh=Gq50IKagmAfx+KtR1kRor/KE8cLkJvCa6loH1PRIiT0=; b=JhiPuzvzkUEKTMaSAOhKcgUBb4mKR0CHtrXwEni/o6Rhk8z8s36otHk/NRvWRqi4Zo bRVc3yeWzw1s4/LWW0QOq6WrCJJ4kkMEP3/LE1Zc2DertGNm76f+ZHaYIhgN1tX6VFdV g32ge/kg+/u5/8qGLTMT8mAnJQJffpcFJOKH1z6GGhgKeHbOlGZPmOYu9aZQyLi5p1+j FcKrRCBORZSzeMEvHrVqnwuQh4Gxo8PgwA5XSyBynhJxJD9AyLfxFwQOB7MLfXKhD2ne XOPxfHXk3IOatTyCybAkHahqfAPMhPcgcxHgB55YLi96seUtSiFkC0vPWacI3YPoOsM0 /KRA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20221208 header.b=s+ibXT5L; 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=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id f15-20020a63754f000000b0052c54de029csi6617684pgn.591.2023.05.11.05.33.34; Thu, 11 May 2023 05:33:46 -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=@google.com header.s=20221208 header.b=s+ibXT5L; 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=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237886AbjEKMK0 (ORCPT + 99 others); Thu, 11 May 2023 08:10:26 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48194 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237782AbjEKMKV (ORCPT ); Thu, 11 May 2023 08:10:21 -0400 Received: from mail-yb1-xb4a.google.com (mail-yb1-xb4a.google.com [IPv6:2607:f8b0:4864:20::b4a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F38FC55B3 for ; Thu, 11 May 2023 05:09:41 -0700 (PDT) Received: by mail-yb1-xb4a.google.com with SMTP id 3f1490d57ef6-b9a7553f95dso16759536276.2 for ; Thu, 11 May 2023 05:09:41 -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=cty1WuR5mOLLKKCpEtyxU/1wc+cUlpR3XriC0n9WjzBL4D7ylMo2dTVlkWJG62sfgg I3rdgc6i0fclN4TLFEy2H3XX91Zgf/KlzOFPw7aWTtGaPxx8Gy0CWiVKpp3xfvnqJFmk ux3EcUA7eNyMpoNnLg/MpNxJ90KV/cMA3oKDf3EUZewnYQ9HnuuzQDjux3jiIdRha4BP +jixZwdude3btzXPIv4a6bhjkbmoq5vbE+uVlXgrJB20LilBivC0AxCKJJKxhh0guMx9 eVFbgkDg+pm4m6tPJMRiKWk0NHpS+qPYO4vE2GkvkBu1yEmRg4xq3SRSLDHecG4ptZq8 wxfQ== X-Gm-Message-State: AC+VfDxGXGhcPivyt4hg7WG5QbMHKhg6dqhvlMXM+qdGf0LTvP34b+LG Xyfq8ROB+3b3BQ4yaDWUrvW1LJ+t6t5QC2wbXg== 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 Content-Type: text/plain; charset="UTF-8" X-Spam-Status: No, score=-9.6 required=5.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE,USER_IN_DEF_DKIM_WL 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: 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; -- 2.40.1.521.gf1e218fcd8-goog