[alsa-devel] Hung task with trace after resume on kernel v3.7-rc6

Takashi Iwai tiwai at suse.de
Mon Nov 19 12:22:05 CET 2012


At Mon, 19 Nov 2012 11:56:32 +0100,
Julian Wollrath wrote:
> 
> > > > I have an Thinkpad X121e with the following soundcard:
> > > > 00:01.1 Audio device [0403]: Advanced Micro Devices [AMD] nee ATI
> > > > Wrestler HDMI Audio [Radeon HD 6250/6310] [1002:1314]
> Of course I did not mean the hdmi device but this one, sorry:
> 00:14.2 Audio device [0403]: Advanced Micro Devices [AMD] nee ATI SBx00
> Azalia (Intel HDA) [1002:4383] (rev 40)
> 
> > So, for this particular issue (at least the recursive suspend call), I
> > think the easiest way is a patch like below.  This is no ideal
> > solution but would be good enough as a bandaid at this late stage for
> > 3.7.  Julian, could you check whether this works?
> Sadly the patch does not work, I still get the spurious responses

Note that spurious responses won't be fixed by this patch at all.
It's a different problem from the hung.  The patch tried only avoiding
the recursive suspend call.

> and a
> trace, which looked minimaly different this time:
> [  240.434881] INFO: task kworker/u:14:3617 blocked for more than 120 seconds.
> [  240.434894] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
> [  240.434901] kworker/u:14    D ffff88011ed128c0     0  3617      2 0x00000000
> [  240.434918]  ffff880106272cd0 0000000000000046 0000000000000086 ffff88011a6e7950
> [  240.434931]  ffff8801178f7fd8 ffff8801178f7fd8 ffff8801178f7fd8 ffff880106272cd0
> [  240.434944]  0000000000000003 ffff8801178f7c20 ffff8801178f7c18 ffff880106272cd0
> [  240.434957] Call Trace:
> [  240.434978]  [<ffffffff81403342>] ? schedule_timeout+0x1e2/0x2a0
> [  240.434992]  [<ffffffff8106c32d>] ? select_task_rq_fair+0x53d/0x5d0
> [  240.435004]  [<ffffffff814049c2>] ? wait_for_common+0xd2/0x180
> [  240.435017]  [<ffffffff810693f0>] ? try_to_wake_up+0x270/0x270
> [  240.435030]  [<ffffffff81052911>] ? flush_work+0xe1/0x160
> [  240.435041]  [<ffffffff81051c10>] ? gcwq_release_assoc_and_unlock+0x40/0x40
> [  240.435052]  [<ffffffff8105369d>] ? __cancel_work_timer+0x5d/0xa0
> [  240.435093]  [<ffffffffa0208f5c>] ? hda_call_codec_suspend+0x14c/0x160 [snd_hda_codec]
> [  240.435114]  [<ffffffffa0208fb0>] ? snd_hda_suspend+0x40/0x60 [snd_hda_codec]
> [  240.435131]  [<ffffffffa01e06cb>] ? azx_bus_reset+0xab/0xc0 [snd_hda_intel]
> [  240.435152]  [<ffffffffa0207e55>] ? codec_exec_verb+0x185/0x1c0 [snd_hda_codec]
> [  240.435173]  [<ffffffffa0207ee8>] ? snd_hda_codec_read+0x58/0x90 [snd_hda_codec]
> [  240.435193]  [<ffffffffa0208b68>] ? snd_hda_shutup_pins+0x58/0x70 [snd_hda_codec]
> [  240.435210]  [<ffffffffa033e369>] ? conexant_suspend+0x9/0x10 [snd_hda_codec_conexant]
> [  240.435229]  [<ffffffffa0208e2e>] ? hda_call_codec_suspend+0x1e/0x160 [snd_hda_codec]
> [  240.435249]  [<ffffffffa0209048>] ? hda_power_work+0x78/0xc0 [snd_hda_codec]
> [  240.435260]  [<ffffffff81052f06>] ? process_one_work+0x126/0x490
> [  240.435280]  [<ffffffffa0208fd0>] ? snd_hda_suspend+0x60/0x60 [snd_hda_codec]
> [  240.435291]  [<ffffffff81054c3d>] ? worker_thread+0x15d/0x450
> [  240.435302]  [<ffffffff81054ae0>] ? flush_delayed_work+0x40/0x40
> [  240.435313]  [<ffffffff810599a3>] ? kthread+0xb3/0xc0
> [  240.435323]  [<ffffffff810598f0>] ? kthread_create_on_node+0x110/0x110
> [  240.435335]  [<ffffffff814061ac>] ? ret_from_fork+0x7c/0xb0
> [  240.435345]  [<ffffffff810598f0>] ? kthread_create_on_node+0x110/0x110

OK, then this code path is irrelevant with the real suspend/resume,
but it's in a normal power-saving path.

Could you try the patch below instead?

> By the way, it seems like I get the traces every 120 seconds and not
> only once, forgot to mention that earlier.

The spurious call (or no proper reply for the verb) indicates that
either the HD-audio controller or the HD-audio codec stalls.  Is yours
a machine with a discrete GPU?  If so, and if you are using
vga-switcheroo or anything manipulating the D-GPU, it's possibly the
cause of the stall.


thanks,

Takashi

---
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index a8e7b00..d9fd439 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -228,7 +228,7 @@ static int codec_exec_verb(struct hda_codec *codec, unsigned int cmd,
 	}
 	mutex_unlock(&bus->cmd_mutex);
 	snd_hda_power_down(codec);
-	if (res && *res == -1 && bus->rirb_error) {
+	if (!codec->in_pm && res && *res == -1 && bus->rirb_error) {
 		if (bus->response_reset) {
 			snd_printd("hda_codec: resetting BUS due to "
 				   "fatal communication error\n");
@@ -238,7 +238,7 @@ static int codec_exec_verb(struct hda_codec *codec, unsigned int cmd,
 		goto again;
 	}
 	/* clear reset-flag when the communication gets recovered */
-	if (!err)
+	if (!err || codec->in_pm)
 		bus->response_reset = 0;
 	return err;
 }
@@ -3655,6 +3655,8 @@ static unsigned int hda_call_codec_suspend(struct hda_codec *codec, bool in_wq)
 {
 	unsigned int state;
 
+	codec->in_pm = 1;
+
 	if (codec->patch_ops.suspend)
 		codec->patch_ops.suspend(codec);
 	hda_cleanup_all_streams(codec);
@@ -3669,6 +3671,7 @@ static unsigned int hda_call_codec_suspend(struct hda_codec *codec, bool in_wq)
 	codec->power_transition = 0;
 	codec->power_jiffies = jiffies;
 	spin_unlock(&codec->power_lock);
+	codec->in_pm = 0;
 	return state;
 }
 
@@ -3677,6 +3680,8 @@ static unsigned int hda_call_codec_suspend(struct hda_codec *codec, bool in_wq)
  */
 static void hda_call_codec_resume(struct hda_codec *codec)
 {
+	codec->in_pm = 1;
+
 	/* set as if powered on for avoiding re-entering the resume
 	 * in the resume / power-save sequence
 	 */
@@ -3700,6 +3705,8 @@ static void hda_call_codec_resume(struct hda_codec *codec)
 		snd_hda_jack_set_dirty_all(codec);
 		snd_hda_jack_report_sync(codec);
 	}
+
+	codec->in_pm = 0;
 	snd_hda_power_down(codec); /* flag down before returning */
 }
 #endif /* CONFIG_PM */
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index baad7bf..8665540 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -871,6 +871,7 @@ struct hda_codec {
 	unsigned int power_on :1;	/* current (global) power-state */
 	unsigned int d3_stop_clk:1;	/* support D3 operation without BCLK */
 	unsigned int pm_down_notified:1; /* PM notified to controller */
+	unsigned int in_pm:1;		/* suspend/resume being performed */
 	int power_transition;	/* power-state in transition */
 	int power_count;	/* current (global) power refcount */
 	struct delayed_work power_work; /* delayed task for powerdown */


More information about the Alsa-devel mailing list