[0/5] ASoC/SoundWire: fix race condition on system suspend

Message ID 20210614180815.153711-1-pierre-louis.bossart@linux.intel.com
Headers show
  • ASoC/SoundWire: fix race condition on system suspend
Related show


Pierre-Louis Bossart June 14, 2021, 6:08 p.m.
This patchset fixes a race condition when a SoundWire codec signals an
'Alert' status during a system suspend, which can happen when e.g. a
jack detection event is detected and handled in a workqueue scheduled
after the link is suspended.

When this happens in pm_runtime suspend, we already use
pm_runtime_get_resume() to force the link to remain active, or resume
immediately, but during a system suspend we don't have this option: we
can't prevent the entire system from suspending just because of a jack
detection or codec-specific event.

This patch suggests instead disabling the implementation-defined or
class-defined IRQs at the start of the suspend, along with an
additional flag to protect against an interrupt thread/workqueue being
scheduled after the interrupts are disabled.

One could argue that the SoundWire core could have handled this case,
which is a fair objection. I chose to keep the interrupt handling
codec-specific since not all codecs can actually generate interrupts,
and what they do during these interrupts is also quite custom - see
e.g. the difference between the RT711 and RT711-SDCA versions. In the
latter case the class-defined interrupts are cleared by the codec
driver, not by the core.

This patchset implies changes to both ASoC and SoundWire, with a
minimal dependency on a sdw_update() helper and its _no_pm version,
both of which should have been added a long time ago for
read-modify-write operations.

This race condition was present in all previous kernel versions but
was only identified in late May in automated tests. We added Fixes tag
to help linux-stable backports, but there's no real point in
back-porting to earlier than 5.10 due to other missing dependencies in
the upstream code.

Pierre-Louis Bossart (5):
  soundwire: export sdw_update() and sdw_update_no_pm()
  ASoC: rt700-sdw: fix race condition on system suspend
  ASoC: rt711-sdw: fix race condition on system suspend
  ASoC: rt5682-sdw: fix race condition on system suspend
  ASoC: rt711-sdca-sdw: fix race condition on system suspend

 drivers/soundwire/bus.c           | 17 +++++++++++-
 drivers/soundwire/bus.h           | 13 ---------
 include/linux/soundwire/sdw.h     |  3 ++
 sound/soc/codecs/rt5682-sdw.c     | 38 +++++++++++++++++++++++--
 sound/soc/codecs/rt5682.h         |  2 ++
 sound/soc/codecs/rt700-sdw.c      | 34 +++++++++++++++++++++--
 sound/soc/codecs/rt700.c          |  4 +++
 sound/soc/codecs/rt700.h          |  2 ++
 sound/soc/codecs/rt711-sdca-sdw.c | 46 +++++++++++++++++++++++++++++--
 sound/soc/codecs/rt711-sdca.c     |  4 +++
 sound/soc/codecs/rt711-sdca.h     |  2 ++
 sound/soc/codecs/rt711-sdw.c      | 34 +++++++++++++++++++++--
 sound/soc/codecs/rt711.c          |  4 +++
 sound/soc/codecs/rt711.h          |  2 ++
 14 files changed, 183 insertions(+), 22 deletions(-)

base-commit: bf28c803f2f4b14716df168e98f6ede4ba955866