From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.remote-ip=100.103.45.18 ARC-Seal: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=none; t=1794590684; b=EhJurlDP3e3/x8OHDKFhI0o2z/EuMuUrzSAhSYLELH03rNZiMQqkMPQLGGQnfB6Y34Xt ILp6IGYSSUkv0r9h3oGq1qitqeqjR/4cHoZEteh7OCDqCzXALtp1Xvl0U2TPxYLi+cV3Y vYWlCQZifI8/BNZCBsasbXC80/0eOdt4955KIQjyR23eMIEmQlIdTBXe4x7/lvQ7CRMgG +8c01/eyTYFaHuzXi6HuXwtxTc9QMPfvpomZI3K2b0oGWJlUAUTr6FR4PhxD5jIskc6s3 31SHj2Wk51FluE225MZNDMi5ELRkXfBDpJFLUe+OJnd5Sv+KVghEW3/AjMAKMjtC7CA== ARC-Message-Signature: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1794590684; h=Received:DKIM-Signature:From:To:Cc:Subject:Date:Message-ID:X-Mailer: In-Reply-To:References:User-Agent:X-stable:X-Patchwork-Hint: MIME-Version:Content-Transfer-Encoding; bh=Yrx9H9d6L2Dgjk98To5NBHmno+VnOMSSijmG/8stK1U=; b=Jx7UP/DMHvJIXBm26KhXuu1HYLnE+Patl1TfJmYpO9afa6LYXd8Y/oBDnv5P5kXXYXOV Kf/1n2sYszMh3inbk3+Vu2n36kRXVIbRJR09/KCxvQ0xgGnxIEL2GFaer0eq3L9wxKG8j sBFgVWwR09eTgPBxtF3WOEqJ2gLH6O68ZCsYYzQQPLwx/JW/fthfa43DwOghLpGF3U+pI 3r38QsPIF9W4gXssT5WH0kqsoHg8v2DTEzJ5hjppbV3zOzwT8r3WbkllBW2/AzLkU+Nuv 1g5ec/9IRCeuxfURe29PQYe4KwfcsOdKVNTfiqI7Dh8W95rHtA770I+3z6NQMROynjg== ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass header.d=linuxfoundation.org header.i=@linuxfoundation.org header.a=rsa-sha256 header.s=korg header.b="Rs/eTRZL"; arc=none smtp.remote-ip=100.103.45.18 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 34FDF606B219; Fri, 13 Nov 2026 17:24:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.a=rsa-sha256 header.s=korg header.b=Rs/eTRZL Received: by smtp.kernel.org (Postfix) with ESMTPSA id 99E9B1F000C6; Fri, 13 Nov 2026 17:24:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=korg; t=1794590683; bh=Yrx9H9d6L2Dgjk98To5NBHmno+VnOMSSijmG/8stK1U=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=Rs/eTRZLL7KKkqvbVcKUTcUhC4VB90K8+h0fr3n9nfwrHApwjasG3CVoJxVcE/wct jiDU0+MG3mg7X/RtlRlh1T+fbrl6FQhcjFntgPjA8AAzCPtnSpvgbbSmMLrzldI5k9 5tQDBmnf35Ty9g1SunxKZpVcbQpMx+WeM4jZlfGM= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Vladyslav Tymoshchuk , Srinivas Kandagatla , Mark Brown , Sasha Levin Subject: [PATCH 6.18 595/686] ASoC: qcom: q6apm-dai: wrap the position of a full ring to 0 Date: Fri, 13 Nov 2026 10:52:08 -0500 Message-ID: <20261113153842.107392455@linuxfoundation.org> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261113153820.902362109@linuxfoundation.org> References: <20261113153820.902362109@linuxfoundation.org> User-Agent: quilt/0.69 X-stable: review X-Patchwork-Hint: ignore X-Mailing-List: patches@lists.linux.dev List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 6.18-stable review patch. If anyone has any objections, please let me know. ------------------ From: Vladyslav Tymoshchuk [ Upstream commit 0ea3e0b196f9dcc17b40ac881a6efef06459975b ] q6apm_dai_pointer() turns the number of period buffers the DSP has returned in the current lap, 1..periods, into a position and reports one frame less than that. Commit a93dad6f4e6a ("ASoC: q6apm-dai: make use of q6apm_get_hw_pointer") added the "- 1" so that the end of the ring is not reported as a position equal to the buffer size. One frame short has a cost once the application stops feeding the stream. The DSP returns the last queued buffer and the position stops at appl_ptr - 1, so avail stays at buffer_size - 1, below the default stop_threshold. The DSP sends nothing more as its queue is empty, so no period interrupt comes either: ALSA never detects the underrun and the stream stays RUNNING. A poll-driven application that missed its last wakeup waits forever, and drain only ends on its timeout, with -EIO. On capture, the last frame of each period is held back until the next one. Before that commit the position wrapped to 0 at the end of the ring. Do that again. A full lap is the start of the ring, and snd_pcm_update_hw_ptr0() accounts for the wrap: the position cannot move by more than one lap between two updates, as each returned buffer calls snd_pcm_period_elapsed() and the DSP holds at most periods buffers. Seen on a OnePlus Pad 3 (SM8750) with PipeWire in interrupt-driven scheduling: after a stall the PCM sat at hw_ptr 78239, appl_ptr 78240 (avail 3839 of 3840) for two hours. Fixes: a93dad6f4e6a ("ASoC: q6apm-dai: make use of q6apm_get_hw_pointer") Cc: stable@vger.kernel.org Assisted-by: Claude:claude-opus-5-5 Signed-off-by: Vladyslav Tymoshchuk Reviewed-by: Srinivas Kandagatla Tested-by: Srinivas Kandagatla Link: https://patch.msgid.link/20261014162703.10172-2-tvlad744@gmail.com Signed-off-by: Mark Brown [ sashal: Adjusted context in q6apm_dai_pointer() because the push/pull-mode branch is absent. ] Signed-off-by: Sasha Levin --- sound/soc/qcom/qdsp6/q6apm-dai.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/sound/soc/qcom/qdsp6/q6apm-dai.c b/sound/soc/qcom/qdsp6/q6apm-dai.c index 54c1a33f9f937..4ea2c9869d5a1 100644 --- a/sound/soc/qcom/qdsp6/q6apm-dai.c +++ b/sound/soc/qcom/qdsp6/q6apm-dai.c @@ -442,11 +442,15 @@ static snd_pcm_uframes_t q6apm_dai_pointer(struct snd_soc_component *component, struct q6apm_dai_rtd *prtd = runtime->private_data; snd_pcm_uframes_t ptr; - ptr = q6apm_get_hw_pointer(prtd->graph, substream->stream) * runtime->period_size; - if (ptr) - return ptr - 1; + /* + * The hw pointer counts the period buffers the DSP has returned in + * this lap, 1..periods. A full lap is the start of the ring again: + * report 0 rather than one frame less, so that the position of a + * drained buffer reaches appl_ptr and ALSA sees the underrun. + */ + ptr = q6apm_get_hw_pointer(prtd->graph, substream->stream) % runtime->periods; - return 0; + return ptr * runtime->period_size; } static int q6apm_dai_hw_params(struct snd_soc_component *component, -- 2.53.0