Skip to content

Commit

Permalink
ALSA: hda - Serialize codec registrations
Browse files Browse the repository at this point in the history
In the current code, the codec registration may happen both at the
codec bind time and the end of the controller probe time.  In a rare
occasion, they race with each other, leading to Oops due to the still
uninitialized card device.

This patch introduces a simple flag to prevent the codec registration
at the codec bind time as long as the controller probe is going on.
The controller probe invokes snd_card_register() that does the whole
registration task, and we don't need to register each piece
beforehand.

Cc: <stable@vger.kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
  • Loading branch information
Takashi Iwai committed Feb 1, 2019
1 parent 35a39f9 commit 305a0ad
Show file tree
Hide file tree
Showing 3 changed files with 5 additions and 1 deletion.
1 change: 1 addition & 0 deletions include/sound/hda_codec.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ struct hda_bus {
unsigned int response_reset:1; /* controller was reset */
unsigned int in_reset:1; /* during reset operation */
unsigned int no_response_fallback:1; /* don't fallback at RIRB error */
unsigned int bus_probing :1; /* during probing process */

int primary_dig_out_type; /* primary digital out PCM type */
unsigned int mixer_assigned; /* codec addr for mixer name */
Expand Down
3 changes: 2 additions & 1 deletion sound/pci/hda/hda_bind.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,8 @@ static int hda_codec_driver_probe(struct device *dev)
err = snd_hda_codec_build_controls(codec);
if (err < 0)
goto error_module;
if (codec->card->registered) {
/* only register after the bus probe finished; otherwise it's racy */
if (!codec->bus->bus_probing && codec->card->registered) {
err = snd_card_register(codec->card);
if (err < 0)
goto error_module;
Expand Down
2 changes: 2 additions & 0 deletions sound/pci/hda/hda_intel.c
Original file line number Diff line number Diff line change
Expand Up @@ -2185,6 +2185,7 @@ static int azx_probe_continue(struct azx *chip)
int dev = chip->dev_index;
int err;

to_hda_bus(bus)->bus_probing = 1;
hda->probe_continued = 1;

/* bind with i915 if needed */
Expand Down Expand Up @@ -2269,6 +2270,7 @@ static int azx_probe_continue(struct azx *chip)
if (err < 0)
hda->init_failed = 1;
complete_all(&hda->probe_wait);
to_hda_bus(bus)->bus_probing = 0;
return err;
}

Expand Down

0 comments on commit 305a0ad

Please sign in to comment.