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

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

3天内不再提示

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

yzcdx 来源:OS与AUTOSAR研究 2023-11-16 16:46 次阅读

1. CPU Idle有什么用?

答案就是“省电”,当多核CPU没有任务执行的时候,这时候需要将除主Core之外的其他Core进行低功耗处理,这件事就是CPU Idle机制做的。

idle状态: 在Linux kernel中,当cpu中没有任务在执行,也没有任何中断、异常信号过来的时候,我们称为处于idle状态,针对这种状态Linux设计了一套cpuidle framework框架,专门用于cpuidle的管理。

Linux系统初始化时会为每个cpu创建一个idle线程,当没有其他进程需要运行的时候,便运行idle线程。

对于不同的功耗及恢复时间的要求,可以根据芯片硬件支持的情况定义多种idle状态,这些状态按功耗从低到高(对应着恢复时间从少到多)排列,利用linux提供的cpuidle框架,用户选用不同的idle策略。这么做的目的就是尽可能在不影响性能的前提下,减少功耗。

ARM64架构中,至少会提供一个wfi的idle状态,有些芯片可能还会提供core下电的idle状态。当CPU idle时,根据预测的idle时间、功耗受益大小、恢复的时间长短,选用一个idle状态,比如进入wfi,关掉CPU的arch timer以便降低功耗,当有中断触发时,CPU又会恢复回来。

2. CPU Idle整体框架

90220672-8456-11ee-939d-92fbcf53809c.png

首先是CPUIdle子系统通过sysfs向userspace提供的节点:

一类是针对整个系统的/sys/devices/system/cpu/cpuidle,通过其中的current_driver、current_governor、available_governors等节点可以获取或设置CPUIdle的驱动信息以及governor。

一类是针对每个CPU的/sys/devices/system/cpu/cpux/cpuidle,通过子节点暴露各个在线的CPU中每个不同Idle级别的name、desc、power、latency等信息。

什么时候进入idle?

关闭一些核可以节省功耗,但关闭之后对时延(性能)必会造成一定的影响,如果在关闭之后很短的时间内就被唤醒,那么就会造成功耗/性能双方都不讨好,在进入退出idle的过程中也是会有功耗的损失的,如果在idle状态下面节省的功耗还无法弥补进入退出该idle的功耗,那么反而会得不偿失。

--解决方法就是:策略。是由cpuidle framework会根据不同的场景来进行仲裁选择使用何种的idle状态。

903a4462-8456-11ee-939d-92fbcf53809c.png

在kernel中cpuidle framework主体包含三个模块,分别为cpuidle core、cpuidle governors和cpuidle drivers,

cpu idle core:负责整体框架,同时负责和sched模块对接,当调度器发现没有任务在执行时候,就切换到idle进程,通知到cpuidle framework的cpuidle core模块要做接下来的idle操作。向cpuidle driver/governors模块提供统一的driver和governors注册和管理接口,向用户空间程序提供governor选择的接口。

cpuidle driver:负责具体idle机制的实现(不同等级下面idle的指标也是在这个模块进行填充),不同的平台会有不同的drivers实现。

cpudile governors:在这个模块进行cpuidle的选择,选择的算法主要是基于切换的功耗代价和系统的延迟容忍度,电源管理的目标就是在保证延迟在系统可以接受的范围内尽可能的节省功耗。

3. Idle状态判断

在Linux系统启动的时候,会在每个cpu上创建对应的idle进程,start_kernel()函数初始化内核需要的所有数据结构,并创建一个名为init的进程(pid=1),当init进程创建完后,cpu的idle进程处于cpu_idle_loop()无限循环中,当没有其他进程处于TASK_RUNNING状态时候,调度器才会执行cpu idle线程,让cpu进入idle模式.其函数调用关系简要概括如下:

start_kernel –> rest_init –> cpu_startup_entry, 在cpu_startup_entry这个函数中,最终程序会进入无限循环do_idle loop中。

这里我们又进入看代码环节,可以参考公众号之前的文章# Linux驱动-IMX6ULL开发板qemu环境搭建,我们修改好qemu启动脚本加-s -S后,在VS中打断点,进行代码查看。

90598a48-8456-11ee-939d-92fbcf53809c.png

cpu_idle_loop()函数中会不断的进行轮询判断

while (1) {
    ...
    if (cpu_is_offline(cpu)) {
            cpuhp_report_idle_dead();
            arch_cpu_idle_dead();
    }

    local_irq_disable();
    arch_cpu_idle_enter();
    ...
}

3. cpuidle core

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

cpuidle device:用于描述CPU核的cpuidle设备。

cpuidle driver:用于描述CPU核的cpuidle驱动。

cpuidle governor:主要根据cpuidle的device和driver状态来选择策略。

90856f32-8456-11ee-939d-92fbcf53809c.png

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

90a281e4-8456-11ee-939d-92fbcf53809c.png

4. 注册初始化

cpuidle初始化包括governor注册、驱动注册和设备注册三部分

4.1 cpuidle governor注册

90d62fd0-8456-11ee-939d-92fbcf53809c.png

cpuidle governor在cpuidle驱动和设备之前注册,内核使用一个链表维护系统中所有已注册的governor。当前新版内核一共支持ladder、menu、teo和haltpoll四种governor,它们都通过调用cpuidle_register_governor函数将自身注册到系统中。

Haltpoll governor:它是用于优化虚拟机性能的一种cpuidle governor。其原理为当vcpu进入idle时,通过guest端执行poll操作,以避免使其陷入host中。它的优点是减少了vm切换和通过ipi唤醒vcpu的成本,但它也造成在guest睡眠时,host无法复用该vcpu对应的物理cpu,从而降低系统吞吐量的问题。

Ladder governor:该governor通过cpu前一次idle状态的驻留时间是否超过该state延迟时间一个特定的值(promotion_time_ns),以及下一个state的延迟时间是否超过系统延迟容忍度,来确定是否需要提升idle state。由于该governor每次只能提升一个state,因此其state提升方式就像梯子一样逐级往上,这也是它的名字由来。它往往用于periodic timer tick system。

Menu governor:直接选择可能满足需求的最深休眠态,就好像你拿着菜单(menu)选菜一样。如果深度的idle state更好,那么就会直接进入到深度的idle state。

Teo governor:采用的策略跟menu governor一样,都是预测接下来会有多长时间能待在idle状态,然后据此选择合适的idle mode。不过它跟menu governor考虑多方因素的策略是不同的。teo的理念是,多数系统上CPU唤醒最频繁的唤醒源都是timer events,而不是设备中断(device interrupts)。timer中断的数量要比其他中断高几个数量级。所以只要依据timer event就可以做好预测工作了。

4.2 cpuidle driver注册

90ec8348-8456-11ee-939d-92fbcf53809c.png

cpuidle驱动注册流程比较简单,它主要包含以下三部分内容

idle state相关参数设置、以及可能的broadcast timer

若设置了local-timer-stop属性,则为每个cpu设置相应的broadcast timer

若为该driver指定了governor,则切换current governor

cpuidle driver的主要工作是定义所支持的cpuidle state,以及state的enter接口,如下面所示,cpudile driver就要负责将平台定义的idle-state信息填充到这个结构体中

91037c92-8456-11ee-939d-92fbcf53809c.png

4.3 cpuidle device注册

911808ba-8456-11ee-939d-92fbcf53809c.png

cpuidle设备注册主要包括初始化一些参数值,将该设备添加到全局设备链表中,然后为其初始化sysfs属性和使能该设备。

注册之后,cpuidle设备、cpuidle驱动及governor之间建立起了连接,最终系统经由cpuidle framework,通过接口来调用下层的接口,进而完成具体的硬件操作。

在现在的SMP系统中,每个cpu core都会有一个对应的cpuidle device,内核是通过使用struct cpuidle_device抽象cpuidle device,该结构体主要成员含义如下:

lenabled:设备是否已经使能 lcpu:该device对应的cpu number llast_residency:该设备上一次停留在idle状态的时间 lstates_usage:记录了该设备的每个idle state的统计信息

5.cpuidle触发流程

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

913292ca-8456-11ee-939d-92fbcf53809c.png

cpu启动完成时,会通过cpu_startup_entry函数将其自身切换到idle线程。除此之外,当某个cpu上没有可运行线程时,也会切换idle线程(上流程没画出,后面梳理进程调度的时候再细讲)。切换idle线程后,最终都会执行idle线程的主函数do_idle,并最终通过该函数将cpu设置为特定的idle state。

其中governor中的select、reflect函数是cpuidle的核心功能,决定了cpuidle状态的选择策略。








审核编辑:刘清

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

    关注

    112

    文章

    6015

    浏览量

    141112
  • Linux系统
    +关注

    关注

    4

    文章

    567

    浏览量

    26923
  • 调度器
    +关注

    关注

    0

    文章

    95

    浏览量

    5161

原文标题:电源管理入门-9 CPU Idle

文章出处:【微信号:OS与AUTOSAR研究,微信公众号:OS与AUTOSAR研究】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    AliOS Things电源管理框架怎么满足物联网设备低功耗需求

    任务处于阻塞状态,将执行idle task。idle task的通常做法是一个while(1)空循环,从汇编视角看是不断执行跳转指令,也就是说当操作系统空闲时,CPU将处于空转
    的头像 发表于 10-29 08:57 4807次阅读

    新建SYSBIOS的idle任务

    在系统的使用中,空闲任务是必不可少的,在windows,linux,ucos ii,MQX 等等和操作系统中,都少不了idle的影子,那么在TI的DSP中的SYSBIOS也不例外。 那么
    发表于 09-15 12:27

    利用串口空闲中断接收数据一直无法判断起空闲状态IDLE

    if(RESET != __HAL_UART_GET_FLAG(&huart2, UART_IT_IDLE) ){}一直无法判断起空闲状态,仿真到这里直接跳过,无法进入if语句内
    发表于 12-28 12:06

    stm32fo72IDLE接收不定长数据

    求助  stm32fo72IDLE接收不定长数据,
    发表于 08-18 06:48

    怎样使用IDLE中断+DMA接收的方式接收数据呢

    怎样使用IDLE中断+DMA接收的方式接收数据呢?怎样使用IDLE中断去判断串口线是否空闲呢?
    发表于 01-27 06:20

    idle线程资源回收问题求解

    线程退出的时候,需要idle线程执行rt_thread_idle_excute才能回收退出线程的资源,但是工作线程比idle线程级别高的话,idle线程得不到执行,跟
    发表于 02-01 14:56

    STM32 HAL CubeMX 串口IDLE接收空闲中断+DMA

    方法:一种是 :IDLE 接收空闲中断+DMA一种是: IDLE 接收空闲中断+RXNE接收数据中断都可完成串口数据的收发知识点介绍:STM32 IDLE 接收空闲中断功能:在使用...
    发表于 12-20 19:39 30次下载
    STM32 HAL CubeMX 串口<b class='flag-5'>IDLE</b>接收空闲中断+DMA

    CPU核心中idle进程作用

    每一个 CPU 核心都会有一个 idle 进程,idle 进程是当系统没有调度 CPU 资源的时候,会进入 idle 进程,而
    的头像 发表于 10-14 09:28 1564次阅读

    CPU进入idle进程状态的流程

    每一个 CPU 核心都会有一个 idle 进程,idle 进程是当系统没有调度 CPU 资源的时候,会进入 idle 进程,而
    的头像 发表于 10-14 09:26 1907次阅读

    使用UART IDLE中断接收不定长数据

    使用UART IDLE中断接收不定长数据
    的头像 发表于 09-18 15:41 603次阅读
    使用UART <b class='flag-5'>IDLE</b>中断接收不定长数据

    如何在connected idle状态下向手机同步音量

    在QCC517x/QCC518x新的ADK下,headset工程如果有音量加减事件,只有当前有A2DP播放音乐或者HFP通话状态下才会给手机发送事件,否则程序会忽略音量加减事件。本文介绍如何在connected idle状态下向
    的头像 发表于 10-20 12:22 361次阅读
    如何在connected <b class='flag-5'>idle</b><b class='flag-5'>状态</b>下向手机同步音量

    python idle在哪里找到

    Python IDLE是一种集成开发环境(Integrated Development Environment,简称IDE),用于编写和运行Python语言的代码。它是Python官方提供的标准
    的头像 发表于 11-29 14:39 499次阅读

    python自带的idle怎么进入

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

    python安装后idle在哪儿

    安装即可。 在安装 Python 后,您将获得一个名为 IDLE(Python Shell)的集成开发环境(IDE)。IDLE 是专门为 Python 设计的一种轻量级的开发环境,它提供了一个交互式
    的头像 发表于 11-29 14:52 487次阅读

    python软件IDLE怎么打多行代码

    IDLE(Integrated Development and Learning Environment)是Python编程语言的一个官方集成开发环境(IDE)。它提供了一个交互式的解释器窗口
    的头像 发表于 11-29 15:00 1906次阅读