linux进程电源管理,Linux电源管理(6)_Generic PM之Suspend功能

本文详细介绍了Linux内核中的Suspend功能,包括Freeze、Standby和STR(Suspend to RAM)三种模式。通过向"/sys/power/state"写入相应指令触发Suspend。文章分析了Suspend过程中的关键步骤,如process freeze、设备管理、平台依赖的电源管理操作等,并探讨了VT switch、freezing of tasks和PM notifier等重要概念。同时,讲解了设备驱动中的device PM ops和platform PM ops在电源管理中的作用及其调用时机。
摘要由CSDN通过智能技术生成

Linux电源管理(6)_Generic PM之Suspend功能

作者:wowo 发布于:2014-8-22 21:40

分类:电源管理子系统

1. 前言

Linux内核提供了三种Suspend: Freeze、Standby和STR(Suspend to RAM),在用户空间向”/sys/power/state”文件分别写入”freeze”、”standby”和”mem”,即可触发它们。

内核中,Suspend及Resume过程涉及到PM Core、Device PM、各个设备的驱动、Platform dependent PM、CPU control等多个模块,涉及了console switch、process freeze、CPU hotplug、wakeup处理等过个知识点。就让我们跟着内核代码,一一见识它们吧。

2. Suspend功能有关的代码分布

内核中Suspend功能有关的代码包括PM core、Device PM、Platform PM等几大块,具体如下:

1)PM Core kernel/power/main.c----提供用户空间接口(/sys/power/state)

kernel/power/suspend.c----Suspend功能的主逻辑

kernel/power/suspend_test.c----Suspend功能的测试逻辑

kernel/power/console.c----Suspend过程中对控制台的处理逻辑

kernel/power/process.c----Suspend过程中对进程的处理逻辑

2)Device PM 设备驱动----具体设备驱动的位置,不再涉及。

3)Platform dependent PM include/linux/suspend.h----定义platform dependent PM有关的操作函数集

arch/xxx/mach-xxx/xxx.c或者

arch/xxx/plat-xxx/xxx.c----平台相关的电源管理操作

3. suspend&resume过程概述

下面图片对Linux suspend&resume过程做了一个概述,读者可以顺着这个流程阅读内核源代码。具体的说明,可以参考后面的代码分析。

f269c7d14a5fee93b3fb6572f7dd0b86.gif

4. 代码分析

4.1 suspend入口

在用户空间执行如下操作: echo "freeze" > /sys/power/state

echo "standby" > /sys/power/state

echo "mem" > /sys/power/state

会通过sysfs触发suspend的执行,相应的处理代码如下: static ssize_t state_store(struct kobject *kobj, struct kobj_attribute *attr,

const char *buf, size_t n)

{

suspend_state_t state;

int error;

error = pm_autosleep_lock();

if (error)

return error;

if (pm_autosleep_state() > PM_SUSPEND_ON) {

error = -EBUSY;

goto out;

}

state = decode_state(buf, n);

if (state < PM_SUSPEND_MAX)

error = pm_suspend(state);

else if (state == PM_SUSPEND_MAX)

error = hibernate();

else

error = -EINVAL;

out:

pm_autosleep_unlock();

return error ? error : n;

}

power_attr(state);

power_attr定义了一个名称为state的attribute文件,该文件的store接口为state_store,该接口在lock住autosleep功能后,解析用户传入的buffer(freeze、standby or mem),转换成state参数。

state参数的类型为suspend_state_t,在include\linux\suspend.h中定义,为电源管理状态在内核中的表示。具体如下:

typedef int __bitwise suspend_state_t;

#define PM_SUSPEND_ON ((__force suspend_state_t) 0)

#define PM_SUSPEND_FREEZE ((__force suspend_state_t) 1)

#define PM_SUSPEND_STANDBY ((__force suspend_state_t) 2)

#define PM_SUSPEND_MEM ((__force suspend_state_t) 3)

#define PM_SUSPEND_MIN PM_SUSPEND_FREEZE

#define PM_SUSPEND_MAX ((__force suspend_state_t) 4)

根据state的值,如果不是(PM_SUSPEND_MAX,对应hibernate功能),则调用pm_suspend接口,进行后续的处理。

pm_suspend在kernel/power/suspend.c定义,处理所有的suspend过程。

4.2 pm_suspend & enter_state

pm_suspend的实现非常简单,简单的做一下参数合法性判断,直接调用enter_state接口,如下:

int pm_suspend(suspend_state_t state)

{

int error;

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++;

}

return error;

}

enter_state代码为:

static int enter_state(suspend_state_t state)

{

int error;

if (!valid_state(state))

return -ENODEV;

if (!mutex_trylock(&pm_mutex))

return -EBUSY;

if (state == PM_SUSPEND_FREEZE)

freeze_begin();

printk(KERN_INFO "PM: Syncing filesystems ... ");

sys_sync();

printk("done.\n");

pr_debug("PM: Preparing system for %s sleep\n", pm_states[state]);

error = suspend_prepare(state);

if (error)

goto Unlock;

if (suspend_test(TEST_FREEZER))

goto Finish;

pr_debug("PM: Entering %s sleep\n", pm_states[state]);

pm_restrict_gfp_mask();

error = suspend_devices_and_enter(state);

pm_restore_gfp_mask();

Finish:

pr_debug("PM: Finishing wakeup.\n");

suspend_finish();

Unlock:

mutex_unlock(&pm_mutex);

return error;

}

主要工作包括:

a)调用valid_state,判断该平台是否支持该电源状态。

suspend的最终目的,是让系统进入可恢复的挂起状态,而该功能必须有平台相关代码的参与才能完成,因此内核PM Core就提供了一系列的回调函数(封装在platform_suspend_ops中),让平台代码(如arch/arm/mach-xxx/pm.c)实现,然后由PM Core在合适的时机调用。这些回调函数包含一个valid函数,就是用来告知PM Core,支持哪些stat

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值