PM: Dump suspend thread stack on dpm suspend timeout
authorBenoit Goby <benoit@android.com>
Fri, 21 Jan 2011 23:53:44 +0000 (15:53 -0800)
committerBenoit Goby <benoit@android.com>
Sat, 22 Jan 2011 00:15:27 +0000 (16:15 -0800)
When a driver takes more than 3 seconds to suspend, dump the suspend
thread stack since BUG() might only dump the idle thread stack.

Change-Id: If854db355fdcf3b773ea20b1b5e031def6d4b114
Signed-off-by: Benoit Goby <benoit@android.com>
drivers/base/power/main.c

index 4a57ecc4ead9231c70c8707040a54fdd38e64a37..33f9aafb47fb9fc5880a1c238942c82d0858b5b3 100644 (file)
@@ -48,6 +48,10 @@ static pm_message_t pm_transition;
 
 static void dpm_drv_timeout(unsigned long data);
 static DEFINE_TIMER(dpm_drv_wd, dpm_drv_timeout, 0, 0);
+static struct {
+       struct device *dev;
+       struct task_struct *tsk;
+} dpm_drv_wd_data;
 
 /*
  * Set once the preparation of devices for a PM transition has started, reset
@@ -601,10 +605,15 @@ static bool is_async(struct device *dev)
  */
 static void dpm_drv_timeout(unsigned long data)
 {
-       struct device *dev = (struct device *) data;
+       struct device *dev = dpm_drv_wd_data.dev;
+       struct task_struct *tsk = dpm_drv_wd_data.tsk;
 
        printk(KERN_EMERG "**** DPM device timeout: %s (%s)\n", dev_name(dev),
               (dev->driver ? dev->driver->name : "no driver"));
+
+       printk(KERN_EMERG "dpm suspend stack:\n");
+       show_stack(tsk, NULL);
+
        BUG();
 }
 
@@ -615,7 +624,9 @@ static void dpm_drv_timeout(unsigned long data)
  */
 static void dpm_drv_wdset(struct device *dev)
 {
-       dpm_drv_wd.data = (unsigned long) dev;
+       dpm_drv_wd_data.dev = dev;
+       dpm_drv_wd_data.tsk = get_current();
+       dpm_drv_wd.data = (unsigned long) &dpm_drv_wd_data;
        mod_timer(&dpm_drv_wd, jiffies + (HZ * 3));
 }