[PATCH] ALSA: core: Fix control device release issue

From: æçç
Date: Tue Jun 02 2020 - 05:48:10 EST


From: zhucancan <zhucancan@xxxxxxxx>
Date: Tue, 2 Jun 2020 16:22:57 +0800
Subject: [PATCH] ALSA: core: Fix control device release issue

We use snd_pcm_add_usr_ctls() in component's .pcm_new(),
unfortunately snd_soc_dapm_add_routes() meets error during
adding card->dapm_routes/of_dapm_routes, it will goto probe_end
to call soc_cleanup_card_resources().

The commit dc82e52492f6 ("ALSA: core: Assure control device
to be registered at last") will make pcm device release is
prior to control device release, but the control device needs
to use pcm pointor, which is already freed by pcm device release.

[ 70.056000] Unable to handle kernel paging request at virtual address ffffff80f2d2c480
[ 70.066139] init: processing action (init.svc.media=*) from (/system/etc/init/mediaserver.rc:1)
[ 70.076311] Mem abort info:
[ 70.126679] ESR = 0x96000047
[ 70.126685] EC = 0x25: DABT (current EL), IL = 32 bits
[ 70.126689] SET = 0, FnV = 0
[ 70.126693] EA = 0, S1PTW = 0
[ 70.126696] Data abort info:
[ 70.126700] ISV = 0, ISS = 0x00000047
[ 70.126704] CM = 0, WnR = 1
[ 70.126710] swapper pgtable: 4k pages, 39-bit VAs, pgdp=00000000a216b000
[ 70.126715] [ffffff80f2d2c480] pgd=00000001ffb7f003, pud=00000001ffb7f003, pmd=00000001ff9e8003, pte=0068000172d2cf12
[ 70.126731] Internal error: Oops: 96000047 [#1] PREEMPT SMP
[ 70.126821] CPU: 0 PID: 5 Comm: kworker/0:0 Tainted: G W O 5.4.12-qgki-debug-g4c7ca9f20 #10
[ 70.126840] Workqueue: events deferred_probe_work_func$2b500e852cead69fde05a2b98ceb2fa6.cfi_jt
[ 70.126845] pstate: 80c00005 (Nzcv daif +PAN +UAO)
[ 70.126854] pc : pcm_usr_ctl_private_free$165f4400ee6732c7c8c8157be0f72518+0x20/0x34
[ 70.126861] lr : snd_ctl_remove+0xf4/0x154
[ 70.126862] sp : ffffffc01007b750
[ 70.126865] x29: ffffffc01007b750 x28: ffffffd973c2bb2c
[ 70.126868] x27: ffffff8107b741a0 x26: dead000000000100
[ 70.126874] x25: 0000000000000002 x24: ffffffd973c2bb8c
[ 70.126877] x23: ffffffd975027c80 x22: ffffffd97415437f
[ 70.126880] x21: 0000000000000001 x20: ffffffd973c37e10
[ 70.126883] x19: ffffff80f2d55d00 x18: ffffff80451de4d0
[ 70.126886] x17: ffffff80f2d58000 x16: 0000000000000400
[ 70.126889] x15: a6fe4e9bdc5a6b05 x14: 0000000000000000
[ 70.126892] x13: ffffffff03ab5408 x12: 0000000000000001
[ 70.126896] x11: 7079542070704120 x10: 0000000000000398
[ 70.126899] x9 : 0000000000000001 x8 : ffffff80f2d2c398
[ 70.126902] x7 : 0000000000000000 x6 : ffffff80f6b4d178
[ 70.126905] x5 : ffffffd97335fe8c x4 : 0000000000000000
[ 70.126908] x3 : ffffffc01007b650 x2 : ffffffc01007b768
[ 70.126911] x1 : 00000000ffffffff x0 : ffffff811ff41480
[ 70.126916] Call trace:
[ 70.126920] pcm_usr_ctl_private_free$165f4400ee6732c7c8c8157be0f72518+0x20/0x34
[ 70.126923] snd_ctl_remove+0xf4/0x154
[ 70.126927] snd_ctl_dev_free$1b8efea49186b79e6e4a39cac5748f1c+0x3c/0x70
[ 70.126930] snd_device_free_all+0x234/0x2c8
[ 70.126934] release_card_device$fb7328386cac0bdf1b3f2f88da79521f+0x24/0xcc
[ 70.126941] device_release$d2fdd8912beb71f9ccc7ca72fceb0522+0x48/0x118
[ 70.126949] kobject_cleanup+0x138/0x25c
[ 70.126952] kobject_put+0x50/0x60
[ 70.126955] put_device+0x14/0x20
[ 70.126957] snd_card_free+0x60/0x98
[ 70.126963] soc_cleanup_card_resources+0x2c/0x420
[ 70.126966] snd_soc_bind_card+0xcc0/0xfa8
[ 70.126968] snd_soc_register_card+0x110/0x128
[ 70.126974] devm_snd_soc_register_card+0x4c/0x90

Fixes: dc82e52492f6 ("ALSA: core: Assure control device to be registered at last")
Signed-off-by: zhucancan <zhucancan@xxxxxxxx>
---
sound/core/device.c | 8 --------
1 file changed, 8 deletions(-)

diff --git a/sound/core/device.c b/sound/core/device.c
index bf0b04a7ee79..1aee0f5623a2 100644
--- a/sound/core/device.c
+++ b/sound/core/device.c
@@ -225,14 +225,6 @@ void snd_device_free_all(struct snd_card *card)

if (snd_BUG_ON(!card))
return;
- list_for_each_entry_safe_reverse(dev, next, &card->devices, list) {
- /* exception: free ctl and lowlevel stuff later */
- if (dev->type == SNDRV_DEV_CONTROL ||
- dev->type == SNDRV_DEV_LOWLEVEL)
- continue;
- __snd_device_free(dev);
- }
-
/* free all */
list_for_each_entry_safe_reverse(dev, next, &card->devices, list)
__snd_device_free(dev);
--
2.21.0