linux 休眠唤醒中设备、总线、用户进程、内核线程调试分析流程

一、suspending consoles打印

代码位置:Kernel/power/suspend.c

函数调用流程:devices_and_enter(suspend_state_t state) --> suspend_console();

void suspend_console(void)

{

if (!console_suspend_enabled) 注释这一行,可以看到休眠后printk的打印

return;

printk("Suspending console(s) (use no_console_suspend to debug)\n");

console_lock();

console_suspended = 1;

up(&console_sem);

}

二、打印linux 内核 bus总线休眠唤醒流程

代码位置:Kernel/drivers/base/power/main.c

dpm_suspend() --> device_suspend() --> __device_suspend()

修改位置:

复制代码
static void pm_dev_dbg(struct device *dev, pm_message_t state, char *info)
{
    dev_printk(KERN_ERR,dev, "%s%s%s\n", info, pm_verb(state.event),
        ((state.event & PM_EVENT_SLEEP) && device_may_wakeup(dev)) ?
        ", may wakeup" : "");
}

内核 log如下:

bus suspend:

329.576315\] reg-fixed-voltage soc:emac_lan_vreg: bus suspend \[ 329.581997\] reg-fixed-voltage soc:rome_vreg: bus suspend \[ 329.587245\] reg-fixed-voltage soc:sdcard_ext_vreg: bus suspend \[ 329.593177\] qcom,mem-acc-regulator 1942131.regulator: bus suspend \[ 329.599144\] pps-gpio soc:pps: bus suspend \[ 329.603183\] platform 7c50000.qcom,emac: bus suspend bus resume: \[ 331.355074\] msm_serial_hs 98b1000.uart: noirq driver resume \[ 331.361022\] PM: noirq resume of devices complete after 17.017 msecs \[ 331.367635\] PM: early resume of devices complete after 0.543 msecs \[ 331.372985\] reg-dummy reg-dummy: bus resume

三、设备休眠唤醒流程打印

代码位置:driver/base/platform.c

3.1 linux设备休眠流程:

复制代码
int platform_pm_suspend(struct device *dev)
{
struct device_driver *drv = dev->driver;
int ret = 0;
...
...

if (drv->pm) {
if (drv->pm->suspend)
ret = drv->pm->suspend(dev);
+pr_info("%s called name = %s\n", __func__, drv->name); //此处添加suspend 设备调试打印
} else {
ret = platform_legacy_suspend(dev, PMSG_SUSPEND);
}

3.2 linux设备唤醒流程

复制代码
int platform_pm_resume(struct device *dev)
{
struct device_driver *drv = dev->driver;
int ret = 0;

...
...

if (drv->pm) {
if (drv->pm->resume)
ret = drv->pm->resume(dev);
pr_info("%s called name = %s\n", __func__, drv->name);//此处添加设备resume打印
} else {
ret = platform_legacy_resume(dev);
}

四、linux内核线程和进程休眠过程打印

函数调用流程:

enter_state(suspend.c)--->suspend_prepare--->suspend_freeze_processes()--->freeze_processes(--->try_to_freeze_tasks--->freeze_task)--->freeze_kernel_processes

可以在kernel/power/process.c中添加如下打印:

复制代码
for_each_process_thread(g,p)

...

pr_info("userspace pid %d, %d\n", p->pid, current->pid);

...

打印效果如下:

327.812216\] PM: suspend entry 2018-09-18 11:53:17.879150194 UTC \[ 327.817117\] PM: Syncing filesystems ... done. \[ 327.823632\] Freezing user space processes ... userspace pid 1 \[ 327.828524\] userspace pid 6 \[ 327.831545\] userspace pid 124 \[ 327.834264\] userspace pid 1345 \[ 327.837216\] userspace pid 2150

对于内核线程休眠的打印可以参考上面在freeze_kernel_processes中添加打印。

五、late_resume和earlysuspend.c加打印

在部分内核版本中可以添加如下log分析问题:

late_resume函数中:

list_for_each_entry_reverse(pos, &early_suspend_handlers, link)

if (pos->resume != NULL) {

pos->resume(pos);

+pr_info("late_resume: func %p\n",pos->resume);

}

early_suspend late_resume添加log

在earlysuspend.c中

static int debug_mask = DEBUG_USER_STATE;

->

static int debug_mask = DEBUG_USER_STATE | DEBUG_SUSPEND |

DEBUG_VERBOSE;

六、休眠唤醒时间长问题排查

参见之前调试文档说明,链接如下:

休眠唤醒(suspend/resume)时长问题分析思路_sched_clock_suspend-CSDN博客

相关推荐
代码AC不AC2 小时前
【Linux】计算机的基石:从冯·诺依曼体系结构到操作系统管理
linux·操作系统·冯诺依曼体系结构
大柏怎么被偷了3 小时前
【Linux】进程等待
linux·运维·服务器
偶像你挑的噻4 小时前
12-Linux驱动开发- SPI子系统
linux·驱动开发·stm32·嵌入式硬件
松涛和鸣4 小时前
16、C 语言高级指针与结构体
linux·c语言·开发语言·数据结构·git·算法
念风4 小时前
[lvgl]如何优雅地向lv_port_linux中添加tslib支持
linux
自由的好好干活5 小时前
使用Qoder编写ztdaq的C#跨平台示例总结
linux·windows·c#·qoder
赖small强6 小时前
【Linux 网络基础】libwebsockets HTTPS 服务端实现机制详解
linux·网络·https·tls·libwebsockets
optimistic_chen6 小时前
【Redis 系列】Redis详解
linux·数据库·redis·缓存·xsheel
低客的黑调6 小时前
了解JVM 结构和运行机制,从小白编程Java 大佬
java·linux·开发语言
想唱rap6 小时前
C++ map和set
linux·运维·服务器·开发语言·c++·算法