]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/commitdiff
ALSA: hda - Serialize codec registrations
authorTakashi Iwai <tiwai@suse.de>
Wed, 30 Jan 2019 16:46:03 +0000 (17:46 +0100)
committerKleber Sacilotto de Souza <kleber.souza@canonical.com>
Wed, 14 Aug 2019 09:18:49 +0000 (11:18 +0200)
BugLink: https://bugs.launchpad.net/bugs/1837664
commit 305a0ade180981686eec1f92aa6252a7c6ebb1cf upstream.

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>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Kamal Mostafa <kamal@canonical.com>
Signed-off-by: Khalid Elmously <khalid.elmously@canonical.com>
sound/pci/hda/hda_bind.c
sound/pci/hda/hda_codec.h
sound/pci/hda/hda_intel.c

index d361bb77ca00d1979a572d7a95d13e8a0563b34f..8db1890605f600e6268b6e1bfe3ef7d4208c1c2e 100644 (file)
@@ -109,7 +109,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;
index a8b1b31f161c26f739892ea6b52e79ba2ebca291..0449c707f78bfb1474b93578e967c5bfe69dc9e1 100644 (file)
@@ -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 */
index 4230800579985a3c2c3126acf877825c045cf499..b0d585b8e1bcf437a7050e4c220a339aa3c82602 100644 (file)
@@ -2253,6 +2253,7 @@ static int azx_probe_continue(struct azx *chip)
        int val;
        int err;
 
+       to_hda_bus(bus)->bus_probing = 1;
        hda->probe_continued = 1;
 
        /* bind with i915 if needed */
@@ -2358,6 +2359,7 @@ i915_power_fail:
        if (err < 0)
                hda->init_failed = 1;
        complete_all(&hda->probe_wait);
+       to_hda_bus(bus)->bus_probing = 0;
        return err;
 }