文档章节

【原创】Linux cpuidle framework

o
 osc_g8254g7s
发布于 2019/08/19 21:47
字数 1166
阅读 30
收藏 0

精选30+云产品,助力企业轻松上云!>>>

背景

  • Read the fucking source code! --By 鲁迅
  • A picture is worth a thousand words. --By 高尔基

说明:

  1. Kernel版本:4.14
  2. ARM64处理器
  3. 使用工具:Source Insight 3.5, Visio

1. 介绍

在Linux OS中,Idle进程的运行会让CPU进入cpuidle状态。当没有其他进程处于运行状态时,Scheduler会选择Idle进程来运行,此时CPU无所事事。

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

cpuidle framework就是用来向上给Scheduler/Sysfs提供使用接口,向下用来对接不同架构的处理器,凡是框架基本都大同小异,屏蔽硬件层并抽象使用接口。

相信你已经猜到了,cpuidle和电源管理相关。

2. 框架

代码路径: driver/cpuidle/cpuidle.c driver/cpuidle/driver.c driver/cpuidle/governor.c driver/cpuidle/sysfs.c kernel/shced/idle.c

老规矩,上图:

简单说明一下吧:调度器发现没有Task处在运行状态时,切换到Idle进程,此时通过cpuidle_idle_call接口调到cpuidle frameworkcpuidle framework会选择合适的策略来决定进入哪种状态,最终回调到底层的平台实现。

SMP处理器都有cpuidle状态,而各个状态下的功耗都不同,是否进入cpuidle状态有两个重要的参考因素:

  • CPU进入-退出cpuidle状态的latency;
  • CPU处在cpuidle状态的功耗;

Latency和功耗的tradeoff,是需要根据实际情况来选择策略的,也就是Governor的作用。

3. 数据结构

cpuidle core抽象出了三个数据结构:

  • cpuidle device:用于描述CPU核;
  • cpuidle driver: 针对CPU核的驱动;
  • cpuidle governor:主要根据cpuidle的device和driver状态来选择策略;

图如下:

3.1 cpuidle device

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

  • registered:该cpu核是否注册进内核中;
  • enabled:该cpu核是否已经使能;
  • cpu:对应的cpu number;
  • last_residency:该cpu核上一次停留在cpuidle状态的时间(us);
  • state_count:cpuidle状态的个数;
  • states_usagestruct cpuidle_state_usage数组,记录每个cpuidle状态的统计信息,包括是否使能、进入该cpuidle状态的次数,停留在该cpuidle状态的总时间(us);
  • kobjs*:与sysfs组织相关,开发给用户层来操作底层;
  • device_list:全局链表,链接到cpuidle_detected_device上;

3.2 cpuidle driver

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

  • bctimer:用于驱动注册时判断是否需要设置broadcast timer;
  • states[]struct cpuidle_state数组,用于描述cpuidle的状态,需要按照功耗从大到小来排序,具体有多少个cpuidle状态,取决于device Tree中的定义,默认已经有state[0],如上图所示。
  • cpumask:用于表明支持哪些CPU核;

struct cpuidle_state中的enter函数,是最终进入cpuidle状态的函数。不同处理器的cpuidle驱动实现,主要是填充state结构体。

3.3 cpuidle governor

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

  • enable/disable:在设备驱动注册和注销的时候调用;
  • select:根据已有状态来选择一个cpuidle状态;
  • reflect:调用该接口告知governor,CPU上一次所处的cpuidle状态是哪个;

流程

cpuidle-arm.c为例,整个注册流程如下图:

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

Idle Task通过cpuidle_enter为入口,调用到cpuidle_framework,流程如下图:

Idle Task调用cpuidle_enter之前,需要先通过governor来运用策略来选择将要进入的cpuidle state。入口为cpuidle_select,当完成状态切换后会调用cpuidle_reflect来将信息更新到governor。具体的图如下:

其中Governor关于状态的策略选择,可以参考menu.c的注释,主要有三个决定因素:

  1. 功耗平衡点,也就是需要权衡考虑cpuidle状态带来的功耗节省和在该cpuidle状态下的停留时间,假如停留时间太短(小于target_residency),则不划算。
  2. 性能影响,那些具有大的延迟退出(exit_latency)的cpuidle state,通常会对工作负载产生较大影响,这个对系统管理员来说是不可接受的。此外,低性能往往也意味着低功耗。
  3. 延迟容忍度(从pmqos框架获取),在满足延迟容忍度latency_req的条件下,选择功耗最小的cpuidle状态。

具体的策略不再分析,请直接看driver/cpuilde/menu.c代码及注释。

o
粉丝 0
博文 500
码字总数 0
作品 0
私信 提问
加载中
请先登录后再评论。
CPU idle框架

在现代操作系统中,往往很多时候并不需要去执行cpu密集型的任务,而每当这个时候,如果去持续的执行循环去等待新的任务发过来,那需要消耗巨大的能量。所以设计人员设计出一种空闲状态以此C...

Peter盼
06/21
0
0
Linux电源管理系统架构和驱动(1)-Linux电源管理全局架构

1. Linux电源管理全局架构 Linux电源管理非常复杂,牵扯到系统级的待机、频率电压变换、系统空闲时的处理以及每个设备驱动对于系统待机的支持和每个设备的运行时电源管理,可以说和系统中的每...

21cnbao
2015/02/21
0
0
Linux Kernel 5.1 正式版发布,非长期支持版本

Linus Torvalds 在内核邮件列表上宣布释出 Linux 5.1,5.2 合并窗口开启。要注意的是 5.1 不是长期支持版本,出于稳定性考虑,最好还是选择 LTS 版本。 5.1 的主要新特性包括: 新的高性能异...

局长
2019/05/07
2.4K
9
Linux时间子系统(十四) tick broadcast framework

一、前言 在内核中,有cpuidle framework可以控制cpu的节电:当没有进程调度到该cpu上执行的时候,swapper进程粉墨登场,将该cpu会被推入到idle状态。当然CPU的idle状态有深有浅,当CPU睡的比...

osc_fbkekcio
2018/02/14
3
0
[原创]EBAZ4205 Linux log打印输出

下载器与板级之间的连接如下:有关iFPGA-Cable,可参考 iFPGA-Cable FT2232H Xilinx / Altera / Lattice 三合一JTAG & UART调试器-详细使用说明 JTAG红色为1脚,请注意 RX接板级TX TX接板级R...

osc_ejr00qw0
2019/04/27
2
0

没有更多内容

加载失败,请刷新页面

加载更多

LINUX_VERSION_CODE与KERNEL_VERSION

由于Linux版本的在不断更新,当设备驱动去兼容不同版本的内核时,需要知道当前使用的内核源码版本,以此来调用对应版本的内核API,这两个宏定义在文件 /usr/include/linux/version.h#defin...

osc_5g68egoj
5分钟前
0
0
JVM09-类加载过程

这一篇我们来学习一下JVM中的类加载过程。说到类的加载过程,我们需要先了解一下JVM中类的生命周期。在JVM中类的生命周期有七个阶段。分别是: 加载(Loading):加载是通过类加载器从不同的...

osc_zai0dt9q
6分钟前
0
0
###豪豪豪豪######2020 推荐系统技术演进趋势了解

读知乎文章《推荐系统技术演进趋势:从召回到排序再到重排》笔记: 《推荐系统技术演进趋势:从召回到排序再到重排》这篇文章主要说了下最近两年,推荐系统技术的一些比较明显的技术发展趋势...

osc_lhmderwy
7分钟前
9
0
SpringBoot入门实现RESTFUL API以及用Postman测试

Model @Data@Builderpublic class Article { private Long id; private String author; private String title; private String content; private Date createTime;}......

osc_7ludm6s2
8分钟前
4
0
Leetcode 83 删除排序链表中的重复元素-链表双指针

维护两个指针,第一个指针指向链表没有重复元素的最后一个位置,第二个指针向后扫描,直到末尾。严格来说,在C++中需要手动释放内存。但在算法题或者Java中不需要这么做。 class Solution {...

osc_n1x6m26g
10分钟前
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部