At Wed, 12 Mar 2014 11:29:38 +0100, Jiri Slaby wrote: > > From: Takashi Iwai <tiwai@xxxxxxx> > > This patch has been added to the 3.12 stable tree. If you have any > objections, please let us know. > > =============== > > commit cbbaa603a03cc46681e24d6b2804b62fde95a2af upstream. > > Some per_pin fields and ELD contents might be changed dynamically in > multiple ways where the concurrent accesses are still opened in the > current code. This patch fixes such possible races by using eld->lock > in appropriate places. > > Reported-by: Anssi Hannula <anssi.hannula@xxxxxx> > Signed-off-by: Takashi Iwai <tiwai@xxxxxxx> > Signed-off-by: Jiri Slaby <jslaby@xxxxxxx> This alone leads to a mutex deadlock, and it needs a few more series of enhancements and fixes. So, either take the whole patches or drop this. a4e9a38b40a0e2f7dad1a0b355896d23fbdd16e0 ALSA: hda - Move mutex from hda_eld to per_pin in HDMI codec driver b55447a7301b12d509df4b2909ed38d125ad83d4 ALSA: hda - Fix typos in patch_hdmi.c da4a7a3926d09c13ae052ede67feb7285e01e3f5 ALSA: hda - Explicitly keep codec powered up in hdmi_present_sense Takashi > --- > sound/pci/hda/patch_hdmi.c | 14 +++++++++++--- > 1 file changed, 11 insertions(+), 3 deletions(-) > > diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c > index 9d1b4589c21b..f576bd6f541d 100644 > --- a/sound/pci/hda/patch_hdmi.c > +++ b/sound/pci/hda/patch_hdmi.c > @@ -1365,6 +1365,7 @@ static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll) > bool update_eld = false; > bool eld_changed = false; > > + mutex_lock(&pin_eld->lock); > pin_eld->monitor_present = !!(present & AC_PINSENSE_PRESENCE); > if (pin_eld->monitor_present) > eld->eld_valid = !!(present & AC_PINSENSE_ELDV); > @@ -1394,11 +1395,10 @@ static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll) > queue_delayed_work(codec->bus->workq, > &per_pin->work, > msecs_to_jiffies(300)); > - return; > + goto unlock; > } > } > > - mutex_lock(&pin_eld->lock); > if (pin_eld->eld_valid && !eld->eld_valid) { > update_eld = true; > eld_changed = true; > @@ -1423,12 +1423,13 @@ static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll) > hdmi_setup_audio_infoframe(codec, per_pin, > per_pin->non_pcm); > } > - mutex_unlock(&pin_eld->lock); > > if (eld_changed) > snd_ctl_notify(codec->bus->card, > SNDRV_CTL_EVENT_MASK_VALUE | SNDRV_CTL_EVENT_MASK_INFO, > &per_pin->eld_ctl->id); > + unlock: > + mutex_unlock(&pin_eld->lock); > } > > static void hdmi_repoll_eld(struct work_struct *work) > @@ -1600,10 +1601,12 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, > int pinctl; > > non_pcm = check_non_pcm_per_cvt(codec, cvt_nid); > + mutex_lock(&per_pin->sink_eld.lock); > per_pin->channels = substream->runtime->channels; > per_pin->setup = true; > > hdmi_setup_audio_infoframe(codec, per_pin, non_pcm); > + mutex_unlock(&per_pin->sink_eld.lock); > > if (spec->dyn_pin_out) { > pinctl = snd_hda_codec_read(codec, pin_nid, 0, > @@ -1658,11 +1661,14 @@ static int hdmi_pcm_close(struct hda_pcm_stream *hinfo, > } > > snd_hda_spdif_ctls_unassign(codec, pin_idx); > + > + mutex_lock(&per_pin->sink_eld.lock); > per_pin->chmap_set = false; > memset(per_pin->chmap, 0, sizeof(per_pin->chmap)); > > per_pin->setup = false; > per_pin->channels = 0; > + mutex_unlock(&per_pin->sink_eld.lock); > } > > return 0; > @@ -1791,10 +1797,12 @@ static int hdmi_chmap_ctl_put(struct snd_kcontrol *kcontrol, > ca = hdmi_manual_channel_allocation(ARRAY_SIZE(chmap), chmap); > if (ca < 0) > return -EINVAL; > + mutex_lock(&per_pin->sink_eld.lock); > per_pin->chmap_set = true; > memcpy(per_pin->chmap, chmap, sizeof(chmap)); > if (prepared) > hdmi_setup_audio_infoframe(codec, per_pin, per_pin->non_pcm); > + mutex_unlock(&per_pin->sink_eld.lock); > > return 0; > } > -- > 1.9.0 > -- To unsubscribe from this list: send the line "unsubscribe stable" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html