From nobody Mon Sep 28 11:39:41 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C896433F5A7 for ; Sat, 22 Aug 2026 16:24:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787415894; cv=none; b=js71hUuE7lrkPLJosFYfLXHBnjBr2KmNKt6EuHQcdT6yiwGt1XXPNJSDvd8XFhX4Oc1CZLkDBVHWcnWdSSH6mRA/2kd3Ay6leQbJyoC/cki2iKL78ULnLmH0roRfkXQOaf6duwhLx1SgOPULoZM0mECijZ+FjAhdihjBwn1GrUs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787415894; c=relaxed/simple; bh=RT/3TaeK0HTG2+4a1yXYCb2lJvhYriYtUyTJ7B/LK4k=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:To; b=jLTn8gAhCyOmHTeceicOP5ij2UPR9XiV0BLpxV+siIQq0JYOmSHUB3sgsWMjuyzZakuuoG2xCAiGyS8uWj2Gf4l3DbC8HHqirPr2qbojH6MJ6ymfyrpgKyZf14GsFfHUUTmJNkhSjNoAKr/ix4xqDdd/222lB1JWIkXGGJ1xlzk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=UgylNvZM; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="UgylNvZM" Received: by smtp.kernel.org (Postfix) with ESMTPS id 7071EC2BCB3; Sat, 22 Aug 2026 16:24:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1787415894; bh=RT/3TaeK0HTG2+4a1yXYCb2lJvhYriYtUyTJ7B/LK4k=; h=From:Date:Subject:To:Reply-To:From; b=UgylNvZMSIrjK1bFHIIxXQ592WUGIuVlH5WftcperrUPf4KTPA0aDjquNDDO2LnH/ 7/BlR0Crpcm0UFXa9XmBdaXpp0Qg6Nc6YIV/ROCjpHa7fFhH6F/iZ0p7vTEJoVNde9 d99r8Tl/ppVWd4d6mJLPQ4CoSuwencf4qkiW9WV4EN0jCaMDpvA1tMjSME6mgPSwnU iQDoo/jNlOM6ptVA5Zc6RvJqhwBCBzkLkpbQtAdx465htAC1nI0jZBPb0MxRXOkk0z 8qf8aab1PH/IXDK0tt/NjPf3+1VE1bztjBXn7vOkE8+n5yB1F/afiGYDz1UYUFtvom 4hAnLAcf8vnhQ== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3C9EFC5DF8C; Sat, 22 Aug 2026 16:24:54 +0000 (UTC) From: FAN YE via B4 Relay Date: Sat, 22 Aug 2026 16:24:54 +0000 Subject: [PATCH] HSI: cmt_speech: fix lost wakeup in cs_char_read() Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260822-cmt-speech-lost-wakeup-v1-1-27aac852bb1a@gmail.com> X-B4-Tracking: v=1; b=H4sIAFXNiWoC/yXMUQ6CMBCE4auQfXaTpSaNchXjA9RRVhGabkETw t2t+vglM/9KhqQwaqqVEhY1ncaCeldR6NvxBtZLMTlxXg7OcXhmtgiEnofJMr/aB+bIe9RHkbL wXqicY8JV37/w6fy3zd0dIX9rtG0fXprfQHoAAAA= X-Change-ID: 20260822-cmt-speech-lost-wakeup-3e1900082660 To: Sebastian Reichel , linux-kernel@vger.kernel.org X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1787415893; l=3480; i=fy15309206903@gmail.com; s=tbnet3; h=from:subject:message-id; bh=HHYSwbyjof/va1JoOEQpdo4eqsNpZlQbFHJKLO1qIgc=; b=TOE/D6VG8bVhPRaDMIwE796KYPhvnS8GTuJEIXvLM6Nu7LjZ2gqF0z7Ffd45FPfltQ1thx1BA sQxJCC5WYFTCItUn/VLyjhw0oAbm2VW2Fwm7XSNeYzkEH3m1EhZM8KZ X-Developer-Key: i=fy15309206903@gmail.com; a=ed25519; pk=6QsQIrI/kruYWIJyCH9ntPMXsHCqF5JtK/DCMtOCzdc= X-Endpoint-Received: by B4 Relay for fy15309206903@gmail.com/tbnet3 with auth_id=929 X-Original-From: FAN YE Reply-To: fy15309206903@gmail.com From: FAN YE A reader can sleep past an available message in cs_char_read(): the queue check happens before prepare_to_wait_exclusive() queues the task, and cs_notify() only wakes tasks already on csdata->wait, so a message queued in between wakes nobody and the reader waits for whichever message shows up next. cs_notify() runs from ssi_pio_thread(), so it can land in that window on SMP, or on a preemptible kernel even with a single CPU. Re-check the queues after being queued and skip schedule() if one already has an entry, mirroring what wait_event() does internally. Fixes: 7f62fe8a5851 ("HSI: cmt_speech: Add cmt-speech driver") Assisted-by: Claude:claude-sonnet-5 Signed-off-by: FAN YE --- Reproduced under QEMU/TCG with a diagnostic build. This driver has no hardware and there is no virtual HSI controller, so the harness hands cs_hsi_client_probe() a fake hsi_client and calls cs_notify() from an RT kthread woken while the reader still holds csdata->lock -- the shape of ssi_pio_thread(), which is what runs msg->complete() on omap_ssi. waitqueue_active() is read inside cs_notify() just before wake_up_interruptible(). One CPU throughout: arm, CONFIG_PREEMPT unpatched waitqueue empty at the wakeup; the reader then sleeps in cs_char_read() on the already queued message and wakes only when an unrelated one arrives -- 6.0 s here, which is simply when the test sends it patched same lost wakeup, read() returns at once (0-1 ms) arm, CONFIG_PREEMPT_VOLUNTARY both waitqueue not empty, so the race cannot form on one CPU: without CONFIG_PREEMPTION spin_unlock_bh() is not a preemption point and the kthread runs only once the reader is already queued; read() returns at once x86_64, preempt=3Dfull and preempt=3Dlazy both as arm CONFIG_PREEMPT Rebuilt and re-run from scratch on a second machine, same results. Built W=3D1 for arm/omap2plus and x86_64; checkpatch --strict clean. --- drivers/hsi/clients/cmt_speech.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/hsi/clients/cmt_speech.c b/drivers/hsi/clients/cmt_spe= ech.c index 7226677ebde7..5be4a4477c44 100644 --- a/drivers/hsi/clients/cmt_speech.c +++ b/drivers/hsi/clients/cmt_speech.c @@ -1132,6 +1132,7 @@ static ssize_t cs_char_read(struct file *file, char _= _user *buf, size_t count, struct cs_char *csdata =3D file->private_data; u32 data; ssize_t retval; + bool empty; =20 if (count < sizeof(data)) return -EINVAL; @@ -1161,7 +1162,18 @@ static ssize_t cs_char_read(struct file *file, char = __user *buf, size_t count, } prepare_to_wait_exclusive(&csdata->wait, &wait, TASK_INTERRUPTIBLE); - schedule(); + /* + * Re-check after being queued: cs_notify() may have queued + * an entry and woken csdata->wait in the window between the + * empty check above and prepare_to_wait_exclusive() adding + * us to it. + */ + spin_lock_bh(&csdata->lock); + empty =3D list_empty(&csdata->chardev_queue) && + list_empty(&csdata->dataind_queue); + spin_unlock_bh(&csdata->lock); + if (empty) + schedule(); finish_wait(&csdata->wait, &wait); } =20 --- base-commit: 26260251022fbc2f248a3d747a9b2b961b18d2d8 change-id: 20260822-cmt-speech-lost-wakeup-3e1900082660 Best regards, -- =20 FAN YE