之前介绍了电源的开机和关机重启,本小节开始介绍省电的技术,其中最暴力的省电方法就是直接拔核hotplug处理,就像需要10个人干活都要吃饭,但是现在活少了最节省的方法就是砍掉几个人,有点像裁员啊。
1. 省电技术概览
对于省电,我们短时间不使用设备的时候可以进行休眠唤醒,长时间不使用就直接关机了。在使用设备的时候可以按照当前需要的性能进行调频处理就是cpufreq和devfeq,当没重度使用或者只运行系统必须进程的时候可以进行cpu休闲(cpuidle)、cpu热插拔(cpu hotplug)、cpu隔离(core isolate)和动态pm(runtime pm)。
cpuidle指的是当某个cpu上没有进程可调度的时候可以暂时局部关掉这个cpu的电源,从而达到省电的目的,当再有进程需要执行的时候再恢复电源。
cpu hotplug指的是我们可以把某个cpu热移除,然后系统就不会再往这个cpu上派任务了,这个cpu就可以放心地完全关闭电源了,当把这个cpu再热插入之后,就对这个cpu恢复供电,这个cpu就可以正常执行任务了。
cpu隔离指的是我们把某个cpu隔离开来,系统不再把它作为进程调度的目标,这样这个cpu就可以长久地进入idle状态了,达到省电的目的。不过cpu隔离并不是专门的省电机制,我们把cpu隔离之后还可以通过set_affinity把进程专门迁移到这个cpu上,这个cpu还会继续运行。cpu隔离能达到一种介于cpuidle和cpu热插拔之间的效果。
runtime pm指的是设备的动态电源管理,系统中存在很多设备,但是并不是每种设备都在一直使用,比如相机可能在大部分时间都不会使用,所以我们可以在大部分时间把相机的电源关闭,在需用相机的时候,再给相机供电。
cpu hotplug和idle的区别?
hotplug是从硬件上拔掉核下电,idle只是从软件上进行处理,也就是说调度器在idle时只是不去调用但是核还是可见的,hotplug直接没这个核了,软件完全不可见。
省电管理可以达到省电的目的,但是也会降低系统的性能,包括响应延迟、带宽、吞吐量等。所以内核又提供了一个pm qos框架,qos是quality of service(服务质量)。pm qos框架一面向顾客提供接口,顾客可以通过这些接口对系统的性能提出要求,一面向各种省电机制下发要求,省电机制在省电的同时也要满足这些性能要求。pm qos的顾客包括内核和进程:对于内核,pm qos提供了接口函数可以直接调用;对于进程,pm qos提供了一些设备文件可以让用户空间进行读写。pm qos对某一项性能指标的要求叫做一个约束,约束分为系统级约束和设备级约束。系统级约束针对的是整个系统的性能要求,设备级约束针对的是某个设备的性能要求。
整体上电源管理也是策略和机制分离的,例如:
hotplug是一个机制,谁去用?可以用户app制定的策略、温控策略、系统suspend时需要等。
cpufreq是策略和机制都包含的。
2. 热插拔代码介绍
cpu的状态包括:possible、present、online、active。
possible状态的cpu:可理解为存在这个cpu资源,但还没有纳入kernel的管理范围。
present状态的cpu:表示已经被kernel接管。
online状态的cpu:表示可以被调度器使用。
active状态的cpu:表示可以被迁移migrate。
linux内核在初始的时候,会创建虚拟总线cpu_subsys,每个cpu调用register_cpu注册时,都会将cpu设备挂在这个总线下。cpu的拔插是通过操作文件节点online实现的,具体拔插操作如下(以cpu1为例):
echo 0 > /sys/devices/system/cpu/cpu1/online //拔核操作echo 1 > /sys/devices/system/cpu/cpu1/online //插核操作
为什么以cpu1为例?
linux cpu热插拔,支持在系统启动后,关闭任意一个secondary cpu(在arm架构中,cpu0为boot cpu,不能被关闭),并在需要时重新打开它。
当操作/sys/devices/system/cpu/cpu1/online文件的时候,会执行drivers/base/core.c中online_store()函数
static ssize_t online_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count){ bool val; int ret; ret = strtobool(buf, &val); if (ret < 0) return ret; ret = lock_device_hotplug_sysfs(); if (ret) return ret; ret = val ? device_online(dev) : device_offline(dev); unlock_device_hotplug(); return ret bus->offline(dev);
drivers/base/cpu.c中
struct bus_type cpu_subsys = { .name = cpu, .dev_name = cpu, .match = cpu_subsys_match,#ifdef config_hotplug_cpu .online = cpu_subsys_online, .offline = cpu_subsys_offline,#endif}; cpu_device_down cpu_down cpu_down_maps_locked _cpu_down cpuhp_down_callbacks takedown_cpu[cpuhp_teardown_cpu] = { .name = cpu:teardown, .startup.single = null, .teardown.single = takedown_cpu, .cant_stop = true,},
do_idle状态机会调用
arch_cpu_idle_dead cpu_die cpu_die psci_cpu_die psci_ops.cpu_off psci_0_2_cpu_off
psci_0_2_cpu_off会调用__psci_cpu_off(psci_0_2_fn_cpu_off, state);最终发送smc指令给atf,上面的cpu down流程汇总如下图:
cpu up流程:
具体代码自己加log,或者打断点看好些。
3. atf中处理
之前在电源管理入门-1关机重启详解中介绍的psci协议部分,这里会发送smc指令到atf。在atf中同理,会处理这些psci协议,这里不详细介绍了。
后记
本篇文章尝试用markdown进行编写,图片用midjourney生成,感觉效果还可以,之前每篇文章的排版很费时间。markdown可以只保留最小的一些格式,把注意力关注到文章内容本身,提高效率才能多写一些文章进行更新。
单片机正常工作的三大条件
微软推更快地安装win10的方法,速度提升6倍
面部识别硬件为何在手机上发展的这么快
南桥芯片和北桥芯片的作用
EN50332—媒体播放器(含耳机)输出音量安全规范测试方案
电源管理入门之CPU热插拔详解
照明企业金莱特中标3.54亿建设项目
薄膜瑕疵检测系统的优势及技术参数
助力射频教学,RIGOL推出经济型频谱分析仪
论物联网的几大优势劣势
光栅测长机测量工件外径步骤及注意事项
韩国、荷兰组建“芯片联盟”
软银宣布与 Iris Ohyama 的最新合作开发新的机器人技术
VOCS在线监测报警系统的功能特点及应用分析
Agilent安捷伦53132A频率计数器12位/秒
古瑞瓦特光伏逆变器怎么样_简单拆解测评
轻薄超曲屏+10亿色显示 天猫超级粉丝日新品荣耀V40轻奢版,售价2999元起
德赛电池2020年其营业收入约为193.89亿元
沃尔沃十几年研发自动驾驶为何还未量产?
百度领投,威马汽车完成30亿元C轮融资