[RFC PATCH] ALSA: hda/hdmi: fix race in handling acomp ELD notification at resume

Kai Vehmanen kai.vehmanen at linux.intel.com
Wed Apr 7 18:40:29 CEST 2021


Hey,

On Wed, 7 Apr 2021, Takashi Iwai wrote:

> On Wed, 07 Apr 2021 17:47:27 +0200, Kai Vehmanen wrote:
> > 
> > When snd-hda-codec-hdmi is used with ASoC HDA controller like SOF (acomp
> > used for ELD notifications), display connection change done during suspend,
> > can be lost due to following sequence of events:
> > 
> >   1. system in S3 suspend
> >   2. DP/HDMI receiver connected
> >   3. system resumed
> >   4. HDA controller resumed, but card->deferred_resume_work not complete
> >   5. acomp eld_notify callback
> >   6. eld_notify ignored as power state is not CTL_POWER_D0
> >   7. HDA resume deferred work completed, power state set to CTL_POWER_D0
> > 
> > This results in losing the notification, and the jack state reported to
> > user-space is not correct.
> 
> Hrm, that's odd.  The logic there is: there is a manual call of
> hdmi_present_sense() for each pin in the resume call back of HDMI
> codec driver, so at the point 7, update_eld() is invoked from
> hdmi_present_sense(), which notifies the state to user-space.

In the bug case, the codec resume is completed in step (4). i915 is up and 
running but no HDMI/DP receiver is yet found/setup at this point. So HDA 
codec driver resumes and concludes no HDMI/DP receivers are available.

A bit later, the HDMI/DP receiver is found and i915 calls eld_notify. But 
as HDA controller's soc_resume_deferred() is still running, 
card->power_state==D2 still at this point. patch_hdmi.c:*pin_eld_notify() 
checks power_state, figures card is not in D0 and ignores the 
notification.

Then another moment later, HDA controller's deferred resume work completes 
and card power state is set to D0, but at this point there are no actions 
left that would trigger reprocessing the ELD nodification.

I now changed this so that if card is in D2, that's good enough and we 
process the notification in patch_hdmi.c:*pin_eld_notify().

> So I don't see what's missing there.  Could you check whether the
> scenario above is correct?  The state is updated in
> snd_hdac_acomp_get_eld() call in sync_eld_via_acomp().  We can see
> what state is returned there at which timing.

At this point, state for the ports is still disconnected (monitor was
connected while system was in suspend).

> The only possible case I can think of now is that the graphics driver
> isn't ready for returning the right value at the HDMI codec resume.
> But this should have been covered by the device link...

Yes, this seems to be the case. The device link seems to be honoured,
but the fact that 1) monitor/receiver is not immediately found, and 2) 
ASoC core does some of the resume work in a work-queue, opens this race 
still.

Seems quite odd indeed, but I've now got reports of systems where this is 
hit, and unfortunately it's very systematic on these systems. By adding 
some arbitrary delay to soc_resume_deferred(), I could easily hit this
myself as well on the systems I have at hand.

Br, Kai


More information about the Alsa-devel mailing list