mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Alban Munari via B4 Relay <devnull+alban.kernel.gmail.com@kernel.org>
To: David Rhodes <david.rhodes@cirrus.com>,
	 Richard Fitzgerald <rf@opensource.cirrus.com>,
	 Jaroslav Kysela <perex@perex.cz>, Takashi Iwai <tiwai@suse.com>,
	 Stefan Binding <sbinding@opensource.cirrus.com>
Cc: linux-sound@vger.kernel.org, patches@opensource.cirrus.com,
	 linux-kernel@vger.kernel.org, stable@vger.kernel.org,
	 Alban Munari <alban.kernel@gmail.com>
Subject: [PATCH] ALSA: hda: cs35l41: Fix hibernation deadlock with the firmware reload
Date: Wed, 11 Nov 2026 20:24:48 +0000	[thread overview]
Message-ID: <20261111-cs35l41-freezable-fw-load-v1-1-ebcaf549b2f7@gmail.com> (raw)

From: Alban Munari <alban.kernel@gmail.com>

cs35l41_system_resume() is also the .thaw and .restore callback, and it
schedules fw_load_work on system_wq. During hibernation, .thaw runs
right after the snapshot is created, while tasks and freezable
workqueues stay frozen until the system powers off. The work calls
request_firmware() with fw_mutex held. When the firmware files are not
cached, the lookup waits for filesystem I/O whose completion runs on a
freezable workqueue (btrfs completes reads on its endio workqueues,
which are WQ_FREEZABLE), so it never returns. The next step of
hibernation then waits for fw_mutex in cs35l41_system_suspend_prep(),
and the machine stays on after the image has been written.

Blocked tasks on an ASUS ROG Strix G17 (G713PI) after the image was
saved, from SysRq-W:

  task:systemd-sleep state:D
   __mutex_lock.constprop.0
   cs35l41_system_suspend_prep [snd_hda_scodec_cs35l41]
   dpm_prepare
   dpm_suspend_start
   hibernation_platform_enter
   hibernate.cold

  task:kworker/15:2 state:D
  Workqueue: events cs35l41_fw_load_work [snd_hda_scodec_cs35l41]
   bit_wait_io
   read_extent_buffer_pages [btrfs]
   btrfs_lookup [btrfs]
   path_openat
   kernel_read_file_from_path_initns
   fw_get_filesystem_firmware
   _request_firmware
   cs35l41_request_firmware_file [snd_hda_scodec_cs35l41]
   cs35l41_smart_amp [snd_hda_scodec_cs35l41]
   cs35l41_fw_load_work [snd_hda_scodec_cs35l41]

Queue the work on system_freezable_wq. After .thaw it then stays
pending until the system powers off, and on resume it runs once tasks
are thawed and the firmware files can be read.

Fixes: 88672826e2a4 ("ALSA: hda: cs35l41: Support System Suspend")
Cc: stable@vger.kernel.org
Signed-off-by: Alban Munari <alban.kernel@gmail.com>
---
Testing: ASUS ROG Strix G17 (G713PI), two CS35L41 amplifiers (CSC3551),
7.2.14-zen1 with this change applied. Before it, every hibernation since
2026-11-02 left the machine on after writing the image; with it, three
hibernations powered off, on mains and on battery, and both amplifiers
reloaded their firmware about one second after tasks restarted. Without
the change, setting "L0 DSP1 Firmware Load" and "R0 DSP1 Firmware Load"
to off before hibernating also avoided the hang. On sound/for-next the
change was build-tested only.

AI assistance: the fix was developed in an interactive session with
Claude Code (Claude Opus 5.5, Anthropic). The model read the journals
and the kernel source, proposed hypotheses and experiments, decoded the
pm_trace value and the pstore records, and wrote the change, the
changelog and these notes. I directed the investigation with a
troubleshooting procedure I wrote for the assistant (research before
experiments, one variable per test), supplied the observations, ran
every experiment on the machine, reviewed the change and tested it as
described above.
---
 sound/hda/codecs/side-codecs/cs35l41_hda.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sound/hda/codecs/side-codecs/cs35l41_hda.c b/sound/hda/codecs/side-codecs/cs35l41_hda.c
index 6fbc194d3347..efe937d18330 100644
--- a/sound/hda/codecs/side-codecs/cs35l41_hda.c
+++ b/sound/hda/codecs/side-codecs/cs35l41_hda.c
@@ -1012,7 +1012,7 @@ static int cs35l41_system_resume(struct device *dev)
 
 	if (cs35l41->request_fw_load && !cs35l41->fw_request_ongoing) {
 		cs35l41->fw_request_ongoing = true;
-		schedule_work(&cs35l41->fw_load_work);
+		queue_work(system_freezable_wq, &cs35l41->fw_load_work);
 	}
 
 	return ret;

---
base-commit: 291d8707fa439ed4ec72552e7770177f6b6514e4
change-id: 20261111-cs35l41-freezable-fw-load-c9542cf8bda7

Best regards,
--  
Alban Munari <alban.kernel@gmail.com>



             reply	other threads:[~2026-11-11 20:25 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-11 20:24 Alban Munari via B4 Relay [this message]
2026-11-12 14:02 ` Stefan Binding (Opensource)

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261111-cs35l41-freezable-fw-load-v1-1-ebcaf549b2f7@gmail.com \
    --to=devnull+alban.kernel.gmail.com@kernel.org \
    --cc=alban.kernel@gmail.com \
    --cc=david.rhodes@cirrus.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-sound@vger.kernel.org \
    --cc=patches@opensource.cirrus.com \
    --cc=perex@perex.cz \
    --cc=rf@opensource.cirrus.com \
    --cc=sbinding@opensource.cirrus.com \
    --cc=stable@vger.kernel.org \
    --cc=tiwai@suse.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®