Skip to contentSkip to conversation

ASoC: sdw_utils: clear stale RT711 device reference on exit

PATCH In review David Cemin 3 participants 3 messages Sep 12 – Sep 25

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 ASoC: sdw_utils: clear stale RT711 device reference on exit

asoc_sdw_rt711_exit() drops the reference held in ctx->headset_codec_dev but leaves the pointer populated. If the card cleanup path reaches the exit hook more than once after a failed or deferred probe, a later invocation reuses the stale pointer and calls put_device() again, underflowing the refcount and leading to oopses when later probe, driver bind, or suspend paths walk the SoundWire bus after the device reference was released. Observed as boot- and suspend-time oopses on an arm64 platform with an RT712 headset codec, reproducible deterministically by repeated machine-driver probe cycling with the codec drivers unloaded.

Clear the pointer after put_device() so repeated cleanup becomes a no-op, which also makes the existing NULL check at the top of the exit hook effective. This matches what commit 046173b98de3 ("ASoC: sdw_utils:
fix double put_device() on aggregated amps") did for the aggregated amp references.

Fixes 811648340707 ("ASoC: Intel: sof_sdw: avoid oops in error handling")
---
 sound/soc/sdw_utils/soc_sdw_rt711.c | 1 +
 1 file changed, 1 insertion(+)
sound/soc/sdw_utils/soc_sdw_rt711.c +1 -0
index 3a3a66b4b737..4707190e160c 100644
@@ -124,6 +124,7 @@ int asoc_sdw_rt711_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_
 
 	device_remove_software_node(ctx->headset_codec_dev);
 	put_device(ctx->headset_codec_dev);
+	ctx->headset_codec_dev = NULL;
 
 	return 0;
 }

base-commit: 841e384b841a3d89c50b4b2d6c5bb6abab1a7e39

Signature · 1 line
2.55.0
#1 lore raw
Quoted 29 lines · David Cemin

asoc_sdw_rt711_exit() drops the reference held in ctx->headset_codec_dev but leaves the pointer populated. If the card cleanup path reaches the exit hook more than once after a failed or deferred probe, a later invocation reuses the stale pointer and calls put_device() again, underflowing the refcount and leading to oopses when later probe, driver bind, or suspend paths walk the SoundWire bus after the device reference was released. Observed as boot- and suspend-time oopses on an arm64 platform with an RT712 headset codec, reproducible deterministically by repeated machine-driver probe cycling with the codec drivers unloaded.

Clear the pointer after put_device() so repeated cleanup becomes a no-op, which also makes the existing NULL check at the top of the exit hook effective. This matches what commit 046173b98de3 ("ASoC: sdw_utils:
fix double put_device() on aggregated amps") did for the aggregated amp references.

Fixes 811648340707 ("ASoC: Intel: sof_sdw: avoid oops in error handling")
---
 sound/soc/sdw_utils/soc_sdw_rt711.c | 1 +
 1 file changed, 1 insertion(+)
sound/soc/sdw_utils/soc_sdw_rt711.c +0 -0
index 3a3a66b4b737..4707190e160c 100644

sound/soc/sdw_utils/soc_sdw_rt711.c int asoc_sdw_rt711_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_ · line 130

Quoted 7 lines
sound/soc/sdw_utils/soc_sdw_rt711.c +1 -0
@@ -124,6 +124,7 @@ int asoc_sdw_rt711_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_
 
 	device_remove_software_node(ctx->headset_codec_dev);
 	put_device(ctx->headset_codec_dev);
+	ctx->headset_codec_dev = NULL;
 
 	return 0;
 }

The analysis looks correct, the only problem is that this code pattern is copy-pasted with the same issue in other files, e.g.

int asoc_sdw_es9356_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link)

{
	struct asoc_sdw_mc_private *ctx = snd_soc_card_get_drvdata(card);

	if (!ctx->headset_codec_dev)
		return 0;

	device_remove_software_node(ctx->headset_codec_dev);
	put_device(ctx->headset_codec_dev);

It'd be best to use a common helper and fix this across the board, no?

maintainer
#2 lore raw
In reply to David Cemin
Quoted 1 line · David Cemin

ASoC: sdw_utils: clear stale RT711 device reference on exit

Applied to

https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-7.4

Thanks!

[1/1] ASoC: sdw_utils: clear stale RT711 device reference on exit

      https://git.kernel.org/broonie/sound/c/7c7df141dcab

All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying to this mail.

Thanks,
Mark