Commit 825a5248 authored by Takashi Iwai's avatar Takashi Iwai
Browse files

ALSA: core: Fix double calls of snd_card_free() via devres

At the transition to the devres-managed card release, we've put the
check of double-free at trigger_card_release().  But this wasn't
enough, as the code path calls snd_card_free() again, and it would
lead to the doubly snd_card_free() calls.

Actually the v1 patch was correct to handle this, but I forgot that
corner case and moved the check to the more obvious place as I thought
it's clearer.  But, as usual, devils live in details.

This patch corrects the check of the double-free to the right place,
with a bit more comments.

Fixes: e8ad415b ("ALSA: core: Add managed card creation")
Link: https://lore.kernel.org/r/20210731083446.26680-1-tiwai@suse.de


Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent fac24b0f
Loading
Loading
Loading
Loading
+10 −4
Original line number Diff line number Diff line
@@ -605,6 +605,15 @@ int snd_card_free(struct snd_card *card)
	DECLARE_COMPLETION_ONSTACK(released);
	int ret;

	/* The call of snd_card_free() is allowed from various code paths;
	 * a manual call from the driver and the call via devres_free, and
	 * we need to avoid double-free. Moreover, the release via devres
	 * may call snd_card_free() twice due to its nature, we need to have
	 * the check here at the beginning.
	 */
	if (card->releasing)
		return 0;

	card->release_completion = &released;
	ret = snd_card_free_when_closed(card);
	if (ret)
@@ -813,9 +822,6 @@ EXPORT_SYMBOL_GPL(snd_card_add_dev_attr);

static void trigger_card_free(void *data)
{
	struct snd_card *card = data;

	if (!card->releasing)
	snd_card_free(data);
}