[Intel-gfx] [PATCH] snd/hda: Only get/put display_power once

Chris Wilson chris at chris-wilson.co.uk
Wed Apr 10 08:17:33 UTC 2019


While we only allow a single display power reference, the current
acquisition/release is racy and a direct call may run concurrently with
a runtime-pm worker. Prevent the double unreference by atomically
tracking the display_power_active cookie.

Testcase: igt/i915_pm_rpm/module-reload #glk-dsi
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
Cc: Takashi Iwai <tiwai at suse.de>
Cc: Imre Deak <imre.deak at intel.com>
---
 sound/hda/hdac_component.c | 23 ++++++++++-------------
 1 file changed, 10 insertions(+), 13 deletions(-)

diff --git a/sound/hda/hdac_component.c b/sound/hda/hdac_component.c
index 13915fdc6a54..f0fd0d83c90e 100644
--- a/sound/hda/hdac_component.c
+++ b/sound/hda/hdac_component.c
@@ -66,6 +66,7 @@ EXPORT_SYMBOL_GPL(snd_hdac_set_codec_wakeup);
 void snd_hdac_display_power(struct hdac_bus *bus, unsigned int idx, bool enable)
 {
 	struct drm_audio_component *acomp = bus->audio_component;
+	unsigned long cookie;
 
 	dev_dbg(bus->dev, "display power %s\n",
 		enable ? "enable" : "disable");
@@ -78,26 +79,22 @@ void snd_hdac_display_power(struct hdac_bus *bus, unsigned int idx, bool enable)
 		return;
 
 	if (bus->display_power_status) {
-		if (!bus->display_power_active) {
-			unsigned long cookie = -1;
-
-			if (acomp->ops->get_power)
-				cookie = acomp->ops->get_power(acomp->dev);
+		cookie = -1;
+		if (acomp->ops->get_power)
+			cookie = acomp->ops->get_power(acomp->dev);
 
+		if (!cmpxchg(&bus->display_power_active, 0, cookie)) {
 			snd_hdac_set_codec_wakeup(bus, true);
 			snd_hdac_set_codec_wakeup(bus, false);
-			bus->display_power_active = cookie;
+			cookie = 0;
 		}
 	} else {
-		if (bus->display_power_active) {
-			unsigned long cookie = bus->display_power_active;
+		cookie = xchg(&bus->display_power_active, 0);
+	}
 
-			if (acomp->ops->put_power)
-				acomp->ops->put_power(acomp->dev, cookie);
+	if (cookie && acomp->ops->put_power)
+		acomp->ops->put_power(acomp->dev, cookie);
 
-			bus->display_power_active = 0;
-		}
-	}
 }
 EXPORT_SYMBOL_GPL(snd_hdac_display_power);
 
-- 
2.20.1



More information about the Intel-gfx mailing list