ubuntu 在 R40e 上 還有 Debian 在 Sempron 2600 上

2011年8月11日 星期四

Suspend Test funtions in Kernel

Power manager options [*] Power Management Debug Support [*] Verbose Power Management debugging [*] Suspend to RAM and standby [*] Test suspend/resume and walealarm during bootup 上面幾個 option 打開。這樣 config 就會有 CONFIG_PM_DEBUG=y CONFIG_PM_VREBOSE=y CONFIG_PM_TEST_SUSPEND=y 這樣,在 kernel/power 下 main.c: static struct attribute * g[] = { &state_attr.attr, #ifdef CONFIG_PM_TRACE &pm_trace_attr.attr, #endif #ifdef CONFIG_SUSPEND_DEVICE_TIME_DEBUG &device_suspend_time_threshold_attr.attr, #endif #ifdef CONFIG_PM_SLEEP &pm_async_attr.attr, #ifdef CONFIG_PM_DEBUG &pm_test_attr.attr, #endif #ifdef CONFIG_USER_WAKELOCK &wake_lock_attr.attr, &wake_unlock_attr.attr, #endif #endif NULL, }; 可以看到每個 option 增加的 entry. CONFIG_PM_DEBUG,就會有 pm_test_attr 這個 entry 宣告的 pm_test_attr 有: #ifdef CONFIG_PM_DEBUG int pm_test_level = TEST_NONE; static const char * const pm_tests[__TEST_AFTER_LAST] = { [TEST_NONE] = "none", [TEST_CORE] = "core", [TEST_CPUS] = "processors", [TEST_PLATFORM] = "platform", [TEST_DEVICES] = "devices", [TEST_FREEZER] = "freezer", }; static ssize_t pm_test_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { char *s = buf; int level; for (level = TEST_FIRST; level <= TEST_MAX; level++) if (pm_tests[level]) { if (level == pm_test_level) s += sprintf(s, "[%s] ", pm_tests[level]); else s += sprintf(s, "%s ", pm_tests[level]); } if (s != buf) /* convert the last space to a newline */ *(s-1) = '\n'; return (s - buf); } static ssize_t pm_test_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t n) { const char * const *s; int level; char *p; int len; int error = -EINVAL; p = memchr(buf, '\n', n); len = p ? p - buf : n; mutex_lock(&pm_mutex); level = TEST_FIRST; for (s = &pm_tests[level]; level <= TEST_MAX; s++, level++) if (*s && len == strlen(*s) && !strncmp(buf, *s, len)) { pm_test_level = level; error = 0; break; } mutex_unlock(&pm_mutex); return error ? error : n; } power_attr(pm_test); #endif /* CONFIG_PM_DEBUG */ 所以在 /sys/power 下會多一個 pm_test。 cat 出來會是 none core processors platform devices freezser 這個功能是用來測試 suspend/resume 的。 從 source code : kernel/power/suspend.c static int suspend_enter(suspend_state_t state) { ..... if (suspend_test(TEST_PLATFORM)) goto Platform_wake; error = disable_nonboot_cpus(); if (error || suspend_test(TEST_CPUS)) goto Enable_cpus; arch_suspend_disable_irqs(); BUG_ON(!irqs_disabled()); error = sysdev_suspend(PMSG_SUSPEND); if (!error) { if (!suspend_test(TEST_CORE)) error = suspend_ops->enter(state); sysdev_resume(); } ... 和 suspend_test( ) function : static int suspend_test(int level) { #ifdef CONFIG_PM_DEBUG if (pm_test_level == level) { printk(KERN_INFO "suspend debug: Waiting for 5 seconds.\n"); mdelay(5000); return 1; } #endif /* !CONFIG_PM_DEBUG */ return 0; } 可以看到, core, processors, platform, devices, freezer 各是不同的 suspend level。
利用 suspend_test( ) 可以讓 suspend 在不同 level 後 resume。

所以可以用來坐測試。

使用方法就是在 console 把要 test 的 level 寫入 /sys/power/pm_test 中。 #echo core > /sys/power/pm_test然後再 trigger suspend... 就會看到 suspend 後 5 sec 就自己 wakeup 了

沒有留言:

標籤

網誌存檔