您的位置:首页 > 运维架构 > Linux

「转载」 Debug Android and Linux suspend and resume (中文)

2017-11-20 17:37 585 查看
转载自:http://blog.chinaunix.net/uid-20321537-id-3067539.html积攒了一些关于调试Android和Linux下面的suspend 和 resume的经验, 在这里和大家分享一下。希望可以有些帮助, (下面没有写Android专用[/b]的, 就是Linux通用[/b]的)。1. no_console_suspend 在kernel启动参数里面加上no_console_suspend, 这个是最基本的, 因为kernel在把console suspend掉以后, 不管里面出了什么事情, 从串口[/b]上都看不到。 大部分在suspend/resume时候的死机都可以通过串口[/b]看到kernel Panic的信息, 这样才会知道是哪里出了问题。因为有的时候resume出错, 或者suspend到很后面出错的console不加这个参数都看不到。2. initcall_debug这个也许知道的人不多, 其实有的时候你不知道哪个driver在suspend/resume的时候出错的时候,很迷茫, 就想在哪里加上一些调试信息来看看是哪里的driver, 其实有些时候加的不合适的话, 会看不到很多有用[/b]的信息。其实kernel本身已经有这样的功能[/b]了(只不过不是很人性化)。 echo 1 > /sys/module/kernel/parameters/initcall_debug echo 9 > /proc/sys/kernel/printk 
第一条命令是打开initcall_debug, 这个是所有的kernel都会有的, 也可以在启动参数里面加initcall_debug来默认打开这个参数, 这样可以调试系统启动。因为这些信息都是KERN_DEBUG级别的, 所以需要提高printk的级别才可以看到, 要不然suspend/resume的时候死掉了,你就没有机会看到这些信息了。3. suspend_test这个方法可以用[/b]rtc这种软件的方式来做循环的suspend/resume, 尽管对于Android这样并不是很足够, (你得模拟一个POWER_KEY上去才够), 但是对于调试Driver的稳定性, 还是有一定用[/b]处的。 不要以为suspend了几次可以, 那么就可以通过几千次的测试。 这个suspend是5秒钟用[/b]RTC唤醒, 然后对于Android, 5秒钟又会自动睡下去, 但是对于通用[/b]Linux, 你得写个小脚本来让他一会再睡下去, 或许这个工具比较有用[/b]rtcwakeup(google rtcwakeup)。使用[/b]方法:编译一个有这个功能[/b]的kernel, make menuconfig 以后选上CONFIG_PM_DEBBUG=yCONFIG_PM_TEST_SUSPEND=y这两个选项烧写新的kernel,然后打开你需要测试的东东, 比如WIFI,3Gecho "core" > /sys/power/pm_testecho "mem" > /sys/power/state这样, 它就会循环休眠和唤醒了。4. wakelock轮到Android的调试了, Android里面和Power相关最大的就是wakelock,  有时候会碰到睡不下去,或者睡到最后弹起来的问题, 就是wakelock引起的,或者说是wakelock的使用[/b]者引起的。怎么调试呢,用[/b]一下两个:echo 15 > /sys/module/wakelock/parameters/debug_maskecho 15 > /sys/module/userwakelock/parameters/debug_mask15是代表16进制的F, 在wakelock里面就是把所有的debug信息打开, 起码现在是。如果以后不够了,估计得输入255.这样你能[/b]看到kernel和frameworks层对于wakelock的操作, 申请和释放。 这样看申请和释放成对否就可以了。注意: wakelock有一种是timeout的, 就是说多少毫秒以后, 会自动释放, 对于这些wakelock, 申请和释放可能[/b]是不成对的。。5. power.0有的时候你会看到系统suspend到了最后, 然后遇到power.0 suspend失败,然后整个系统都又resume起来了。 这个是android专有的,因为power.0是android注册到suspend最后的一个回调, 它会在CPU进入[/b]suspend之前检查一下有没有wakelock, 如果这时候还有没有释放的wakelock, 那么它会返回-EBUSY然后导致整个suspend失败。 调试这个问题的方法就是把上面wakelock的debug信息打开, 然后看看是哪个家伙去申请了wakelock,然后干掉它。这个错误的错误信息大概是这样的:pm_noirq_op(): platform_pm_suspend_noirq+0x0/0x38 returns -11
PM: Device power.0 failed to suspend late: error -116. earlysuspend差点忘掉这个哥们, android里面另外一个pm相关的大东东, 同样可以加:echo 15 > /sys/module/earlysuspend/parameters/debug_mask来把相关的debug信息打印出来, 比如那个earlysuspend要被call之类的。7. suspend/resume time.有的时候你要调试suspend/resume的时间太慢的问题。 一种方法是用[/b]initcall_debug, 然后把printk的时间戳打上, 然后看哪个很慢。但是这样会让你的生活很枯燥:)我有一个patch,专门用[/b]来调试这个问题的,但是upstream不接受, 说非要用[/b]这种折磨人的方法才行, 但是如果你想用[/b]可以下下来打上去用[/b]一下。地址在这里:http://www.spinics.net/lists/linux-pm/msg24063.html

 power_debug.patch.txt 
  
用[/b]法是, 打上这个PATCH以后, 在KERNEL里面选择上PM_DEBUG, SUSPEND_DEVICE_TIME_DEBUG 这两个选项。然后echo 微秒 > /sys/power/device_suspend_time_threshold比如echo 50000  > /sys/power/device_suspend_time_threshold  注意这里是微秒哦。。。 它会把在suspend/resume的时候慢的那些driver打出来,然后你去干掉它。。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: