linux的睡眠.docx

上传人:b****2 文档编号:669967 上传时间:2022-10-12 格式:DOCX 页数:21 大小:22.04KB
下载 相关 举报
linux的睡眠.docx_第1页
第1页 / 共21页
linux的睡眠.docx_第2页
第2页 / 共21页
linux的睡眠.docx_第3页
第3页 / 共21页
linux的睡眠.docx_第4页
第4页 / 共21页
linux的睡眠.docx_第5页
第5页 / 共21页
点击查看更多>>
下载资源
资源描述

linux的睡眠.docx

《linux的睡眠.docx》由会员分享,可在线阅读,更多相关《linux的睡眠.docx(21页珍藏版)》请在冰豆网上搜索。

linux的睡眠.docx

linux的睡眠

这篇报告旨在弄清楚在x86平台下,睡眠的过程中,设备的行为是什么,特别时pcie设备,以及与ACPI有什么关系。

Linux内核提供了三种Suspend:

Freeze、Standby和STR(SuspendtoRAM),在用户空间向”/sys/power/state”文件分别写入”freeze”、”standby”和”mem”,即可触发它们。

这个报告涉及到的主要是STR(SuspendtoRAM)。

在用户空间执行如下操作:

echo"mem">/sys/power/state

然后内核中会进入在kernel/power/suspend.c定义的pm_suspend,处理所有的suspend过程。

intpm_suspend(suspend_state_tstate)

{

interror;

if(state<=PM_SUSPEND_ON||state>=PM_SUSPEND_MAX)

return-EINVAL;

error=enter_state(state);

if(error){

suspend_stats.fail++;

dpm_save_failed_errno(error);

}else{

suspend_stats.success++;

}

returnerror;

}

EXPORT_SYMBOL(pm_suspend);

enter_state代码为:

staticintenter_state(suspend_state_tstate)

{

interror;

trace_suspend_resume(TPS("suspend_enter"),state,true);

if(state==PM_SUSPEND_FREEZE){

#ifdefCONFIG_PM_DEBUG

if(pm_test_level!

=TEST_NONE&&pm_test_level<=TEST_CPUS){

pr_warning("PM:

Unsupportedtestmodeforsuspendtoidle,"

"pleasechoosenone/freezer/devices/platform.\n");

return-EAGAIN;

}

#endif

}elseif(!

valid_state(state)){//判断该平台是否支持该电源状态

return-EINVAL;

}

if(!

mutex_trylock(&pm_mutex))

return-EBUSY;

if(state==PM_SUSPEND_FREEZE)

freeze_begin();

#ifndefCONFIG_SUSPEND_SKIP_SYNC

trace_suspend_resume(TPS("sync_filesystems"),0,true);

printk(KERN_INFO"PM:

Syncingfilesystems...");

sys_sync();//文件系统同步

printk("done.\n");

trace_suspend_resume(TPS("sync_filesystems"),0,false);

#endif

pr_debug("PM:

Preparingsystemforsleep(%s)\n",pm_states[state]);

pm_suspend_clear_flags();

error=suspend_prepare(state);进行suspend前准备,主要是切换console,冻结线程和进程。

if(error)

gotoUnlock;

if(suspend_test(TEST_FREEZER))

gotoFinish;

trace_suspend_resume(TPS("suspend_enter"),state,false);

pr_debug("PM:

Suspendingsystem(%s)\n",pm_states[state]);

pm_restrict_gfp_mask();

error=suspend_devices_and_enter(state);这个接口就是负责挂起和恢复的所有实际的动作,过程相对复杂。

pm_restore_gfp_mask();

Finish:

pr_debug("PM:

Finishingwakeup.\n");

suspend_finish();

Unlock:

mutex_unlock(&pm_mutex);

returnerror;

}

 

 

suspend_devices_and_enter,kernel/power/suspend.c

intsuspend_devices_and_enter(suspend_state_tstate)

{

interror;

boolwakeup=false;

if(!

sleep_state_supported(state))

return-ENOSYS;

error=platform_suspend_begin(state);//调用suspend_ops的begin回调(有的话),通知平台代码,以便让其作相应的处理(需要的话)。

可能失败,需要跳至Close处执行恢复操作(suspend_ops->end)。

if(error)

gotoClose;

suspend_console();

suspend_test_start();

error=dpm_suspend_start(PMSG_SUSPEND);这个函数就是设备相关的电源管理的代码

if(error){

pr_err("PM:

Somedevicesfailedtosuspend,orearlywakeeventdetected\n");

gotoRecover_platform;

}

suspend_test_finish("suspenddevices");

if(suspend_test(TEST_DEVICES))

gotoRecover_platform;

do{

error=suspend_enter(state,&wakeup);

}while(!

error&&!

wakeup&&platform_suspend_again(state));

Resume_devices:

suspend_test_start();

dpm_resume_end(PMSG_RESUME);

suspend_test_finish("resumedevices");

trace_suspend_resume(TPS("resume_console"),state,true);

resume_console();

trace_suspend_resume(TPS("resume_console"),state,false);

Close:

platform_resume_end(state);

returnerror;

Recover_platform:

platform_recover(state);

gotoResume_devices;

}

do{

error=suspend_enter(state,&wakeup);

}while(!

error&&!

wakeup&&platform_suspend_again(state));

Resume_devices:

suspend_test_start();

dpm_resume_end(PMSG_RESUME);

suspend_test_finish("resumedevices");

trace_suspend_resume(TPS("resume_console"),state,true);

resume_console();

trace_suspend_resume(TPS("resume_console"),state,false);

Close:

platform_resume_end(state);

returnerror;

Recover_platform:

platform_recover(state);

gotoResume_devices;

}

dpm_suspend_start,drivers/base/power/main.c

intdpm_suspend_start(pm_message_tstate)

{

interror;

error=dpm_prepare(state);//设备在suspend之前需要做的一些工作,与下面的dpm_suspend(state)处理流程类似,所以以下面的dpm_suspend(state)做具体分析。

if(error){

suspend_stats.failed_prepare++;

dpm_save_failed_step(SUSPEND_PREPARE);

}else

error=dpm_suspend(state);

returnerror;

}

EXPORT_SYMBOL_GPL(dpm_suspend_start);

dpm_suspend,drivers/base/power/main.c

intdpm_suspend(pm_message_tstate)

{

ktime_tstarttime=ktime_get();

interror=0;

trace_suspend_resume(TPS("dpm_suspend"),state.event,true);

might_sleep();

cpufreq_suspend();

mutex_lock(&dpm_list_mtx);

pm_transition=state;

async_error=0;

while(!

list_empty(&dpm_prepared_list)){

structdevice*dev=to_device(dpm_prepared_list.prev);

get_device(dev);

mutex_unlock(&dpm_list_mtx);

error=device_suspend(dev);//对所有在dpm_list链表中的设备执行

mutex_lock(&dpm_list_mtx);

if(error){

pm_dev_err(dev,state,"",error);

dpm_save_failed_dev(dev_name(dev));

put_device(dev);

break;

}

if(!

list_empty(&dev->power.entry))

list_move(&dev->power.entry,&dpm_suspended_list);

put_device(dev);

if(async_error)

b

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 总结汇报 > 学习总结

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1