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

From: Takashi Iwai
Date: Tue Jun 02 2020 - 08:49:46 EST


On Tue, 02 Jun 2020 11:48:04 +0200,
æçç wrote:
>
> 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

Which driver or core contains this function? I can't find it in the
latest upstream code.

Overall, it looks rather like an issue of the driver side, not the
ALSA core. If the relevant control is tied with a PCM stream, it has
to be freed individually beforehand at the time when the stream gets
freed.


thanks,

Takashi

> [ 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
>
>
>
>
>
>
>
>
>