Message ID | 1406910649-4028-3-git-send-email-amit.pundir@linaro.org |
---|---|
State | New |
Headers | show |
> Existing printk timestamps in a dmesg only log suspend activities > (e.g. filesystem syncs, freezing/unfreezing tasks etc) while the > system has already started to enter/exit the suspend state. Sometimes > it is handy to have suspend entry/exit overhead information while > debugging suspend issues. This patch print markers with wall > timestamps at suspend Entry and Exit in the kernel log. These > timestamps can be used to compute how long the system spent in > low-power suspend state plus the entry/exit overhead. > > This patch comes from the Android patch set, where its been used to > help diagnose battery life problems in various Android-based devices. Thanks Amit. For this patch, we're actually moving away from primarily analyzing the kernel log of suspend times, instead logging this info via userspace. Android is now using the wakeup_count suspend interface (previously autosleep was employed), allowing userspace to be informed whenever suspend is entered and resumed. The Android batterystats service logs timestamps for these, along with the wakeup reason info previously discussed on the linux-pm list. But it still is occasionally useful to see the suspend times when debugging problems based on the kernel log. Todd -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c index ed35a47..28726b6 100644 --- a/kernel/power/suspend.c +++ b/kernel/power/suspend.c @@ -26,6 +26,7 @@ #include <linux/suspend.h> #include <linux/syscore_ops.h> #include <linux/ftrace.h> +#include <linux/rtc.h> #include <trace/events/power.h> #include <linux/compiler.h> @@ -417,6 +418,18 @@ static int enter_state(suspend_state_t state) return error; } +static void pm_suspend_marker(char *annotation) +{ + struct timespec ts; + struct rtc_time tm; + + getnstimeofday(&ts); + rtc_time_to_tm(ts.tv_sec, &tm); + pr_info("PM: suspend %s %d-%02d-%02d %02d:%02d:%02d.%09lu UTC\n", + annotation, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, + tm.tm_hour, tm.tm_min, tm.tm_sec, ts.tv_nsec); +} + /** * pm_suspend - Externally visible function for suspending the system. * @state: System sleep state to enter. @@ -431,6 +444,7 @@ int pm_suspend(suspend_state_t state) if (state <= PM_SUSPEND_ON || state >= PM_SUSPEND_MAX) return -EINVAL; + pm_suspend_marker("entry"); error = enter_state(state); if (error) { suspend_stats.fail++; @@ -438,6 +452,7 @@ int pm_suspend(suspend_state_t state) } else { suspend_stats.success++; } + pm_suspend_marker("exit"); return error; } EXPORT_SYMBOL(pm_suspend);