ALSA: hda: optimize the probe codec process
authorsongxiebing <songxiebing@kylinos.cn>
Fri, 1 Mar 2024 01:18:41 +0000 (09:18 +0800)
committerTakashi Iwai <tiwai@suse.de>
Fri, 1 Mar 2024 10:46:30 +0000 (11:46 +0100)
In azx_probe_codecs function, when bus->codec_mask is becomes to 0(no codecs),
execute azx_init_chip, bus->codec_mask will be initialized to a value again,
this causes snd_hda_codec_new function to run, the process is as follows:
-->snd_hda_codec_new
-->snd_hda_codec_device_init
-->snd_hdac_device_init---snd_hdac_read_parm(...AC_PAR_VENDOR_ID) 2s
       ---snd_hdac_read_parm(...AC_PAR_VENDOR_ID) 2s
       ---snd_hdac_read_parm(...AC_PAR_SUBSYSTEM_ID) 2s
       ---snd_hdac_read_parm(...AC_PAR_REV_ID) 2s
       ---snd_hdac_read_parm(...AC_PAR_NODE_COUNT) 2s
when no codecs, read communication is error, each command will be polled for
2 second, a total of 10s, it is easy to some problem.
like this:
  2 [   14.833404][ 6] [  T164] hda 0006:00: Codec #0 probe error; disabling it...
  3 [   14.844178][ 6] [  T164] hda 0006:00: codec_mask = 0x1
  4 [   14.880532][ 6] [  T164] hda 0006:00: too slow response, last cmd=0x0f0000
  5 [   15.891988][ 6] [  T164] hda 0006:00: too slow response, last cmd=0x0f0000
  6 [   16.978090][ 6] [  T164] hda 0006:00: too slow response, last cmd=0x0f0001
  7 [   18.140895][ 6] [  T164] hda 0006:00: too slow response, last cmd=0x0f0002
  8 [   19.135516][ 6] [  T164] hda 0006:00: too slow response, last cmd=0x0f0004
 10 [   19.900086][ 6] [  T164] hda 0006:00: no codecs initialized
 11 [   45.573398][ 2] [    C2] watchdog: BUG: soft lockup - CPU#2 stuck for 22s! [kworker/2:0:25]

Here, when bus->codec_mask is 0, use a direct break to avoid execute snd_hda_codec_new function.

Signed-off-by: songxiebing <songxiebing@kylinos.cn>
Link: https://lore.kernel.org/r/20240301011841.7247-1-soxiebing@163.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/pci/hda/hda_controller.c

index 3e7bfeee84fdadf136108212e286fd16eb3c819d..efe98f6f19a373b9c343861cf9bdc2039885d7e2 100644 (file)
@@ -1207,6 +1207,9 @@ int azx_probe_codecs(struct azx *chip, unsigned int max_slots)
                                dev_warn(chip->card->dev,
                                         "Codec #%d probe error; disabling it...\n", c);
                                bus->codec_mask &= ~(1 << c);
+                               /* no codecs */
+                               if (bus->codec_mask == 0)
+                                       break;
                                /* More badly, accessing to a non-existing
                                 * codec often screws up the controller chip,
                                 * and disturbs the further communications.