0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

CPU核心中idle进程作用

Linux阅码场 来源:Linux阅码场 作者:Linux阅码场 2022-10-14 09:28 次阅读

cpuidle framework

每一个 CPU 核心都会有一个 idle 进程,idle 进程是当系统没有调度 CPU 资源的时候,会进入 idle 进程,而 idle 进程的作用就是不使用 CPU,以此达到省电的目的。

ARM64架构中,当CPU Idle时,会调用WFI指令(wait for interrupt),关掉CPU的Clock以便降低功耗,当有外设中断触发时,CPU又会恢复回来。

cpuidle core 是 cpuidle framework 的核心模块,负责抽象出 cpuidle device、cpuidle driver 和 cpuidle governor 三个实体,如下所示:

88ab3e4e-4b55-11ed-a3b6-dac502259ad0.png

cpuidle core 抽象出了 cpuidle device、cpuidle driver 和 cpuidle governor 三个数据结构。

数据结构

cpuidle_device

针对每个CPU核都对应一个struct cpuidle_device结构,主要字段介绍如下

structcpuidle_device{
//该cpu核是否注册进内核中
unsignedintregistered:1;
//该cpu核是否已经使能
unsignedintenabled:1;
unsignedintuse_deepest_state:1;
//对应的cpunumber
unsignedintcpu;

//该cpu核上一次停留在cpuidle状态的时间(us)
intlast_residency;
//记录每个cpuidle状态的统计信息,包括是否使能、进入该cpuidle状态的次数,停留在该cpuidle状态的总时间(us)
structcpuidle_state_usagestates_usage[CPUIDLE_STATE_MAX];
......
};

对应的注册接口是 cpuidle_register_device。

cpuidle_driver

cpuidle driver用于驱动一个或多个CPU核,关键字段描述如下:

structcpuidle_driver{
constchar*name;
structmodule*owner;
intrefcnt;

//用于驱动注册时判断是否需要设置broadcasttimer
unsignedintbctimer:1;
//用于描述cpuidle的状态,需要按照功耗从大到小来排序,具体有多少个cpuidle状态
structcpuidle_statestates[CPUIDLE_STATE_MAX];
......
};

//CPU有多种不同的idle级别。这些idle级别有不同的功耗和延迟,从而可以在不同的场景下使用
//主要包括exit_latency、power_usage、target_residency。这些特性是governor制定idle策略的依据
structcpuidle_state{
charname[CPUIDLE_NAME_LEN];
chardesc[CPUIDLE_DESC_LEN];

unsignedintflags;
//CPU从该idle state下返回运行状态的延迟,单位为us。它决定了CPU在idle状态和run状态之间切换的效率,如果延迟过大,将会影响系统性能;
unsignedintexit_latency;/*inUS*/
//CPU在该idlestate下的功耗,单位为mW
intpower_usage;/*inmW*/
//期望的停留时间,单位为us。进入和退出idle state是需要消耗额外的能量的,如果在idle状态停留的时间过短,节省的功耗少于额外的消耗,则得不偿失。governor会根据该字段,结合当前的系统情况(如可以idle多久),选择idle level;
unsignedinttarget_residency;/*inUS*/
booldisabled;/*disabledonallCPUs*/

//进入该state的回调函数
int(*enter)(structcpuidle_device*dev,
structcpuidle_driver*drv,
intindex);

//CPU长时间不需要工作时(称作offline),可调用该回调函数。
int(*enter_dead)(structcpuidle_device*dev,intindex);
......
};

对应的注册接口是 cpuidle_register_driver。

cpuidle_governor

governor 结构主要提供不同的回调函数,最终由 menu_governor 填充,主要字段如下:

structcpuidle_governor{
charname[CPUIDLE_NAME_LEN];
structlist_headgovernor_list;
//governor的级别,正常情况下,kernel会选择系统中rating值最大的governor作为当前governor
unsignedintrating;

//在设备驱动注册和注销的时候调用
int(*enable)(structcpuidle_driver*drv,
structcpuidle_device*dev);
void(*disable)(structcpuidle_driver*drv,
structcpuidle_device*dev);

//根据当前系统的运行状况,以及各个idlestate的特性,选择一个state(即决策)
int(*select)(structcpuidle_driver*drv,
structcpuidle_device*dev,
bool*stop_tick);
//通过该回调函数,可以告知governor,系统上一次所处的idlestate是哪个
void(*reflect)(structcpuidle_device*dev,intindex);
};

对应的注册接口是 cpuidle_register_governor。

流程

我们先看下设备和驱动的注册过程:

88d8a2f8-4b55-11ed-a3b6-dac502259ad0.png

注册之后便将设备和驱动建立起连接关系了,最终 cpuidle framework 的用户便可通过接口来调用下层的接口,进而完成具体的硬件操作。

下面看下 CPU 进入 idle 状态的流程图:

88ea354a-4b55-11ed-a3b6-dac502259ad0.png

可以看出,最终是通过 PSCI 来实现 CPU 的 suspend。

PSCI

PSCI, Power State Coordination Interface,由ARM定义的电源管理接口规范,通常由Firmware来实现,而Linux系统可以通过smc/hvc指令来进入不同的Exception Level,进而调用对应的实现。

88ffd206-4b55-11ed-a3b6-dac502259ad0.png

PSCI 支持如下功能:

CPU hotplug (on/off)

CPU idle (suspend/resume)

System suspend/resume

System shutdown and reset

每个功能和ATF之间的调用接口如下所示:

892f577e-4b55-11ed-a3b6-dac502259ad0.png

审核编辑:彭静
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • cpu
    cpu
    +关注

    关注

    68

    文章

    10794

    浏览量

    210698
  • 接口
    +关注

    关注

    33

    文章

    8432

    浏览量

    150684
  • 数据
    +关注

    关注

    8

    文章

    6790

    浏览量

    88721
收藏 人收藏

    评论

    相关推荐

    Linux进程怎么绑定CPU

    昨天在群里有朋友问:把进程绑定到某个 CPU 上运行是怎么实现的。
    发表于 10-26 10:26 1836次阅读

    电源管理入门-CPU Idle有什么用?Idle状态判断

    答案就是“省电”,当多核CPU没有任务执行的时候,这时候需要将除主Core之外的其他Core进行低功耗处理,这件事就是CPU Idle机制做的。
    的头像 发表于 11-16 16:46 7035次阅读
    电源管理入门-<b class='flag-5'>CPU</b> <b class='flag-5'>Idle</b>有什么用?<b class='flag-5'>Idle</b>状态判断

    【资料共享】Linux Kernel 核心中文手册

    Linux Kernel 核心中文手册, .chm格式便于查阅
    发表于 09-09 12:28

    【Nanopi2试用体验】高级(十):进程绑定CPU核心

    的ID编译程序:# gcc aaa.c -lpthread # ./a.out这段代码将使nanopifunction线程在所有cpu核心中依次执行一段时间,在NanoPi2上的执行结果为:可以看到线程
    发表于 02-03 17:28

    进程和线程区别

    `1、进程和线程的区别和联系进程(process)和线程(thread)是操作系统的基本概念,但是它们比较抽象,不容易掌握。计算机的核心CPU,它承担了所有的计算任务。它就像一座工厂
    发表于 11-30 14:06

    线程与6个arm核心中的一个绑定请问如何解绑?

    问题:在ubuntu TX2平台上,将线程与6个arm核心中的一个绑定,想在运行时下解绑定,采用的方法是:用get接口获取当前线程绑定的mask;判断当前线程是否与某个核心绑定;如果已经绑定,再调用
    发表于 09-07 14:25

    什么是CPU核心

    什么是CPU核心 核心(Die)又称为内核,是CPU最重要的组成部分
    发表于 12-17 10:57 1207次阅读

    CPU缓存是什么意思_CPU缓存有什么作用

    由于处理器是核心硬件,相信我们在选择处理器的时候都会去关心处理器参数方面,而在处理器核心参数中,我们经常会看到缓存(Cache)这个参数,那么CPU的缓存有什么作用呢?下面小编科普一下
    发表于 05-19 09:24 7417次阅读

    基于linux eBPF的进程off-cpu的方法

    提起off-CPU就不得不提on-cpu,on-cpu是在线程(进程)在CPU上运行的消耗,off-cp
    的头像 发表于 09-25 15:41 3061次阅读
    基于linux eBPF的<b class='flag-5'>进程</b>off-<b class='flag-5'>cpu</b>的方法

    进程绑定到某个 CPU 上运行是怎么实现?

    昨天在群里有朋友问:把进程绑定到某个 CPU 上运行是怎么实现的。 首先,我们先来了解下将进程CPU 进行绑定的好处。 进程绑定
    的头像 发表于 07-02 09:55 2362次阅读

    讲讲线程、进程CPU中的超线程

    因此,超线程简单来讲就是把这些不能公用的资源加倍。而那些流水线上的操作逻辑电路、ALU单元等则可以不用复制。以此实现多个线程同时在一个CPU核心中进行处理。
    的头像 发表于 08-05 16:38 2438次阅读

    CPU进入idle进程状态的流程

    每一个 CPU 核心都会有一个 idle 进程idle 进程是当系统没有调度
    的头像 发表于 10-14 09:26 2278次阅读

    python自带的idle怎么进入

    Python自带的IDLE是一个集成开发环境(Integrated Development Environment),它通过提供编辑器和交互式解释器,使得Python的开发变得更加简单和便捷。本文将
    的头像 发表于 11-29 14:51 2108次阅读

    kernel到android核心启动过程

    kernel_init 与kthreadd,创建完后系统通过init_idle_bootup_task蜕化为idle进程cpu_idle)。 调用kernel_thread()创建1
    的头像 发表于 12-04 16:59 841次阅读
    kernel到android<b class='flag-5'>核心</b>启动过程

    如何在内核中启动secondary cpu

    给调度器之前,并没有实际的业务进程,而我们知道内核中cpu在空闲时会执行idle进程。因此,在其启动之前需要为每个cpu初始化一个
    的头像 发表于 12-05 15:46 503次阅读
    如何在内核中启动secondary <b class='flag-5'>cpu</b>