Skip to content

Commit

Permalink
ALSA: core: Assure control device to be registered at last
Browse files Browse the repository at this point in the history
The commit 289ca02 ("ALSA: Use priority list for managing device
list") changed the way to register/disconnect/free devices via a
single priority list.  This helped to make behavior consistent, but it
also changed a slight behavior change: namely, the control device is
registered earlier than others, while it was supposed to be the very
last one.

I've put SNDRV_DEV_CONTROL in the current position as the release of
ctl elements often conflict with the private ctl elements some PCM or
other components may create, which often leads to a double-free.
But, the order of register and disconnect should be indeed fixed as
expected in the early days: the control device gets registered at
last, and disconnected at first.

This patch changes the priority list order to move SNDRV_DEV_CONTROL
as the last guy to assure the register / disconnect order.  Meanwhile,
for keeping the messy resource release order, manually treat the
control and lowlevel devices as last freed one.

Additional note:
The lowlevel device is the device where a card driver creates at
probe.  And, we still keep the release order control -> lowlevel, as
there might  be link from a control element back to a lowlevel object.

Fixes: 289ca02 ("ALSA: Use priority list for managing device list")
Reported-by: Tzung-Bi Shih <[email protected]>
Tested-by: Tzung-Bi Shih <[email protected]>
Signed-off-by: Takashi Iwai <[email protected]>
  • Loading branch information
tiwai committed May 17, 2018
1 parent 377a879 commit dc82e52
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 1 deletion.
2 changes: 1 addition & 1 deletion include/sound/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ struct completion;
*/
enum snd_device_type {
SNDRV_DEV_LOWLEVEL,
SNDRV_DEV_CONTROL,
SNDRV_DEV_INFO,
SNDRV_DEV_BUS,
SNDRV_DEV_CODEC,
Expand All @@ -62,6 +61,7 @@ enum snd_device_type {
SNDRV_DEV_SEQUENCER,
SNDRV_DEV_HWDEP,
SNDRV_DEV_JACK,
SNDRV_DEV_CONTROL, /* NOTE: this must be the last one */
};

enum snd_device_state {
Expand Down
9 changes: 9 additions & 0 deletions sound/core/device.c
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,15 @@ 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);
}

0 comments on commit dc82e52

Please sign in to comment.