一文搞懂linux cpu dvfs

本文详细介绍了Linux系统中的CPU动态频率与电压调整(CPUDVFS)框架,包括其作用、框架结构、关键数据结构如structcpufreq_policy和governors的工作原理,以及初始化和工作流程。重点探讨了ondemand、conservative和Schedutil等调频策略的特点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 介绍

CPU dvfs(dynamic voltage frequency scaling)子系统负责cpu运行时,对其频率及电压进行调整,以求性能满足的前提下,cpu的功耗尽可能低。

芯片的CMOS电路的功耗有个计算公式,比较复杂,简单来说功耗跟电压平方成正比,跟频率成正比,因此CPU dvfs在涉及到电压调整的时候,功耗受益还是很明显的。但是仅调频的话,收益是比较小的,因为频率对应着算力,当频率减少,对应的算力也减弱,这样执行时间也会变长。

CPU dvfs framework(也常被称为cpufreq framework)和其他的linux framework类似,主要解决两个问题:什么时候调频调压,怎么调频调压。cpufreq driver提供调频调压的机制,cpufreq governor提供不同的策略,cpufreq core对通用的调频逻辑做抽象,为上层提供功能、接口封装,对下层调用抽象封装的硬件控制接口,此外,还借助频率电压对opp(operating performance points)功能,clk driver、regulator driver对频率及电压做时钟及电压的调整。

2. 框架

cpu dvfs框图

  • cpufreq core:是cpufreq framework的核心模块,和kernel其它framework类似,主要实现三类功能
    • 抽象调频调压的公共逻辑和接口,主要围绕struct cpufreq_driver、struct cpufreq_policy和struct cpufreq_governor三个数据结构进行。
    • 以sysfs的形式向用户空间提供统一的接口,以notifier的形式向其它driver提供频率变化的通知。
    • 提供CPU频率和电压控制的驱动框架,方便底层driver的开发;同时,提供governor框架,用于实现不同的频率调整机制。
  • cpufreq governor:负责调频调压的各种策略,每种governor计算频率的方式不同,根据提供的频率范围和参数(阈值等),计算合适的频率。
    • userspace:用户通过操作scaling_setspeed文件节点操作频率及电压的调整。
    • ondemand:根据CPU当前的使用率,动态调整cpu的频率及电压。Sched通过调用ondemand注册进来的回调函数来触发负载的估算,它以一定时间间隔对系统负载进行采样,按需调整cpu的频率及电压,若当前cpu的利用率超过设定的阈值,就会立即调整到最大的频率。调频速度快,但是不够精确。
    • conservative:类似ondemand,在调频调节时会平滑一下,以防最大、最小频率之间来回跳变。调整的时候会以一定步长调整,而不是直接调整到目标值。同时会周期的计算系统负载,用以决定调到什么频率。
    • schedutil:通过将自己的调频策略注册到hook,在负载发生变化的时候,会调用该hook,此时就可以进行调频决策或执行调频动作。前面的调频策略都是周期采样计算cpu负载有滞后性,精度也有限,而schedutil可以使用PELT(per entity load tracking)或者WALT(window assist load tracking)准确的计算task的负载。如果支持fast_switch的功能,可以在中断上下文直接进行调频。
  • cpufreq driver:负责平台相关的调频调压机制的实现,基于cpu subsystem driver、OPP、clock driver、regulator driver等模块,提供对CPU频率和电压的控制。
  • cpufreq stats:负责调频信息和各频点运行时间等统计,提供每个cpu的cpufreq有关的统计信息。

3. 数据结构

  • struct cpufreq_policy:linux使用cpufreq policy来抽象cpu设备的调频调压功能,用于描述不同的policy,包含频率表、cpuinfo等各种信息,并且每个policy都会对应某个具体的governor。
  • struct cpufreq_governor:不同policy的管理策略,根据使用场景的不同,会有不同的调频调压策略。
  • struct cpufreq_driver:用于描述cpufreq的驱动,是驱动工程师最关注的结构。

cpu dvfs数据结构

4. 初始化及工作流程

4.1 初始化流程

cpufreq_register_driver函数为cpufreqdriver注册的入口,驱动程序通过调用该函数进行初始化,并传入相关的struct cpufreq_driver,cpufreq_register_driver会调用subsys_interface_register,最终执行回调函数cpufreq_add_dev。

系统中可以同时存在多个governor,policy通过cpufreq_policy->governor指针和某个governor相关联。要想一个governor能够被使用,首先要把该governor注册到cpufreq framework中。

cpufreq core定义了一个全局链表变量:cpufreq_governor_list,注册函数首先根据governor的名称,通过__find_governor()函数查找该governor是否已经被注册过,如果没有被注册过,则把代表该governor的结构体添加到cpufreq_governor_list链表中。

cpu dvfs初始化流程

4.2 工作流程

不同的governor的触发调频调压流程不一样,这里以schedutil governor为例。

CFS负载变化的时候或者RT、DL任务状态更新的时候,就会启动调频。这几个scheduler类会调用cpufreq_update_util函数(前面注册进来的hook函数)触发schedutil工作。每个cpu最终会回调到sugov_upate_shared或者sugov_upate_single函数中的一个。

由于是从scheduler里直接调用下来的,最终执行调频切换时,无论是快速路径触发的简单写寄存器,还是慢速路径触发的kthread都不会占用过多时间或者调度开销。

具体的触发时机如下:

cpu dvfs工作流程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值