[alsa-devel] [RFC PATCH] ALSA: hda - Explicitly keep codec powered up in hdmi_present_sense
Takashi Iwai
tiwai at suse.de
Wed Dec 18 11:31:54 CET 2013
At Wed, 18 Dec 2013 10:46:04 +0100,
David Henningsson wrote:
>
> This should help us avoid the following mutex deadlock:
>
> [] mutex_lock+0x2a/0x50
> [] hdmi_present_sense+0x53/0x3a0 [snd_hda_codec_hdmi]
> [] generic_hdmi_resume+0x5a/0x70 [snd_hda_codec_hdmi]
> [] hda_call_codec_resume+0xec/0x1d0 [snd_hda_codec]
> [] snd_hda_power_save+0x1e4/0x280 [snd_hda_codec]
> [] codec_exec_verb+0x5f/0x290 [snd_hda_codec]
> [] snd_hda_codec_read+0x5b/0x90 [snd_hda_codec]
> [] snd_hdmi_get_eld_size+0x1e/0x20 [snd_hda_codec_hdmi]
> [] snd_hdmi_get_eld+0x2c/0xd0 [snd_hda_codec_hdmi]
> [] hdmi_present_sense+0x9a/0x3a0 [snd_hda_codec_hdmi]
> [] hdmi_repoll_eld+0x34/0x50 [snd_hda_codec_hdmi]
>
> Signed-off-by: David Henningsson <david.henningsson at canonical.com>
> ---
> sound/pci/hda/patch_hdmi.c | 6 +++++-
> 1 file changed, 5 insertions(+), 1 deletion(-)
>
> So; I came across the above stack trace when testing the latest daily HDA driver.
> It only happened once, and jack polling was enabled while testing, if that matters.
>
> As you can see, the hdmi_present_sense is called recursively, and my patch doesn't
> really fix that; it should only make the consequences less severe (because now
> the recursion would be in the very beginning, i e, at snd_hda_power_up).
>
> I first thought just unlocking the mutex before calling pin_get_eld could do,
> but not sure if we really want to do that. Nevertheless, I haven't done much
> of the power management work anyway, so I'd like you to double check it and potentially
> come up with better ideas if you have any.
This should work well enough, as far as I see, so I applied it now.
thanks,
Takashi
>
> diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
> index f5060fc..977db17 100644
> --- a/sound/pci/hda/patch_hdmi.c
> +++ b/sound/pci/hda/patch_hdmi.c
> @@ -1496,11 +1496,14 @@ static bool hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll)
> * specification worked this way. Hence, we just ignore the data in
> * the unsolicited response to avoid custom WARs.
> */
> - int present = snd_hda_pin_sense(codec, pin_nid);
> + int present;
> bool update_eld = false;
> bool eld_changed = false;
> bool ret;
>
> + snd_hda_power_up(codec);
> + present = snd_hda_pin_sense(codec, pin_nid);
> +
> mutex_lock(&per_pin->lock);
> pin_eld->monitor_present = !!(present & AC_PINSENSE_PRESENCE);
> if (pin_eld->monitor_present)
> @@ -1573,6 +1576,7 @@ static bool hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll)
> jack->block_report = !ret;
>
> mutex_unlock(&per_pin->lock);
> + snd_hda_power_down(codec);
> return ret;
> }
>
> --
> 1.7.9.5
>
More information about the Alsa-devel
mailing list