艾巴生活网

您现在的位置是:主页>科技 >内容

科技

idle process进程(CPU进入idle进程状态的流程)

2024-03-14 18:17:01科技帅气的蚂蚁
指南框架每个CPU内核都会有一个空闲进程。当系统不调度CPU资源时,空闲进程将进入空闲进程。空闲进程的作用是通过不使用CPU来省电。在ARM64

idle process进程(CPU进入idle进程状态的流程)

指南框架

每个CPU内核都会有一个空闲进程。当系统不调度CPU资源时,空闲进程将进入空闲进程。空闲进程的作用是通过不使用CPU来省电。

在ARM64架构中,当CPU空闲时,它会调用WFI指令(等待中断),关闭CPU 时钟来降低功耗,当外设中断触发时,CPU将再次恢复。

Cpuidle core是Cpuidle框架的核心模块,负责抽象出三个实体:cpuidle设备、cpuidle驱动和cpuidle调控器,如下图所示:

Cpuidle核心抽象了三种数据结构:cpuidle设备、cpuidle驱动程序和cpuidle调控器。

数据结构

cpuidle_device

每个CPU核对应一个struct cpuidle_device结构。主要字段如下

structcpuidle _ device {//CPU unsignedintregistered:1在内核unsigned:1;cpu内核是否启用了unsigned:1;unsignedintuse _ deepth _ state:1;//对应的cpunumberunsignedintcpu//上一次这个cpu内核停留在cpuidle状态(us)int last _ residency;//记录每个cpuidle状态的统计信息,包括是否使能,进入cpuidle状态的次数,停留在cpuidle状态的总时间(US)。struct CPUIDLE _ STATE _ USAGE States _ USAGE[CPUIDLE _ STATE _ MAX];};

对应的注册接口是cpuidle_register_device。

cpuidle_driver

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

struct guidle _ driver { const char * name;structmodule *所有者;intrefcnt//用于确定驱动注册时是否需要设置BroadcastTimerunSignedIntBCTimer:1;//用来描述cpuidle的状态,需要按照功耗排序。有多少个cpuidle状态struct CPUIDLE _ STATES[CPUIDLE _ STATE _ MAX]?};//CPU有各种不同的空闲级别。这些空闲级别具有不同的功耗和延迟,因此可以用于不同的场景。//主要包括exit_latency,power_usage,target_residency。这些特征是调控器制定空闲策略的基础:struct cpuidle _ state { charname[cpuidle _ name _ len];char desc[CPUIDLE _ desc _ LEN];unsignedintflags//CPU从空闲状态返回运行状态的延迟时间,单位为us。它决定了CPU在空闲状态和运行状态之间切换的效率。如果延迟过大,会影响系统性能。unsignedintexit _ latency//此idlestate下的CPU功耗,以mWintpower_usage表示;/在美国的预期停留时间。进入和退出空闲状态需要额外的能量。如果停留在空闲状态的时间太短,节省下来的功耗会小于额外的消耗,得不偿失。调速器将选择怠速等级;根据这个字段和当前系统情况(比如可以空闲多长时间);unsignedinttarget _ residencybool disabled;/进入状态的回调函数int(* Enter)(structcpuidle _ device * dev,structcpuidle _ driver * drv,int index);//这个回调函数可以在//CPU不不需要长时间工作(称为离线)。int(* enter _ dead)(structcpuidle _ device * dev,int index);};

对应的注册接口是cpuidle_register_driver。

cpuidle_governor

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

struct puidle _ governor { charname[c puidle _ NAME _ LEN];structlist _ headgovernor _ list//省长的级别。一般情况下,内核会选择系统中rating值最大的调控器作为当前的governorunsignedintrating//设备驱动注册注销时调用int(* enable)(struct cpuidle _ driver * drv,struct cpuidle _ device * dev);void(* disable)(structcpuidle _ driver * drv,structcpuidle _ device * dev);//根据当前系统的运行状态和各个idlestate的特点,选择一个状态(即decision)int(* select)(struct cpuidle _ driver * drv,struct cpuidle _ device * dev,bool * stop _ tick);//通过这个回调函数,可以告诉调控器系统上次在哪个void(* reflect)(struct cpuidle _ device * dev,intindex);};

对应的注册接口是cpuidle_register_governor。

程序

让让我们先来看看设备和驱动程序的注册过程:

注册后,设备和驱动程序之间的连接就建立了。最后,cpuidle框架的用户可以通过接口调用下层接口,完成具体的硬件操作。

让让我们来看看CPU进入空闲状态的流程图:

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

PSCI

Psci,power state coordination interface,由ARM定义的电源管理接口规范,通常由固件实现,而Linux系统可以通过smc/hvc指令进入不同的异常级别,然后调用相应的实现。

PSCI支持以下功能:

CPU热插拔(开/关)

CPU空闲(挂起/恢复)

系统挂起/恢复

系统关闭和复位

每个函数与ATF之间的调用接口如下:

审计刘清