日期 内核版本 CPU架构 作者
2019.04.06 Linux-4.4 PowerPC LoneHugo

系列文章:https://blog.csdn.net/Vince_/article/details/89070001

CPU子系统的定义

CPU子系统为cgroup中对CPU资源进行限制和分配的子系统,属于内核调度系统功能范畴,其定义在kernel/sched/core.c文件中,由宏CONFIG_CGROUP_SCHED包裹。CPU子系统采用两种调度类进行调度,分别是CFS(Completely Fair Scheduler)和RT(Real-Time Scheduler)。在Linux中,CFS对普通优先级进程采用时间片轮转优先级策略实现调度,其中较高优先级的进程获得更多的时间片,也即更高比例的CPU资源利用时间,从而在调度过程中对剩余时间片更多的进程优先进行调度执行。而RT则为实时进程对应的调度类,对实时进程进行轮转调度。

CPU子系统结构如下:

struct cgroup_subsys cpu_cgrp_subsys = {.css_alloc  = cpu_cgroup_css_alloc,.css_online = cpu_cgroup_css_online,.css_released  = cpu_cgroup_css_released,.css_free    = cpu_cgroup_css_free,.fork        = cpu_cgroup_fork,.can_attach  = cpu_cgroup_can_attach,.attach        = cpu_cgroup_attach,.legacy_cftypes    = cpu_files,.early_init    = 1,
};

对struct cgroup_subsys的成员做了一些赋值,包括生成的用户接口配置文件并指定相应的操作函数,具体信息下面展开。

cftype文件接口

static struct cftype cpu_files[] = {
#ifdef CONFIG_FAIR_GROUP_SCHED{.name = "shares",.read_u64 = cpu_shares_read_u64,.write_u64 = cpu_shares_write_u64,},
#endif
#ifdef CONFIG_CFS_BANDWIDTH{.name = "cfs_quota_us",.read_s64 = cpu_cfs_quota_read_s64,.write_s64 = cpu_cfs_quota_write_s64,},{.name = "cfs_period_us",.read_u64 = cpu_cfs_period_read_u64,.write_u64 = cpu_cfs_period_write_u64,},{.name = "stat",.seq_show = cpu_stats_show,},
#endif
#ifdef CONFIG_RT_GROUP_SCHED{.name = "rt_runtime_us",.read_s64 = cpu_rt_runtime_read,.write_s64 = cpu_rt_runtime_write,},{.name = "rt_period_us",.read_u64 = cpu_rt_period_read_uint,.write_u64 = cpu_rt_period_write_uint,},
#endif{ }   /* terminate */
};

以上接口文件对应到前面提到的调度类参数信息,分别对应到CFS和RT。

cpu.shares

对应cgroup组内进程能占有的CPU资源,这是一个相对数值,比如设定三个与CPU子系统关联的cgroup math/finance/physics,分别设置其cpu.shares为256/256/512,则三个cgroup内进程占有的CPU资源比例为1:1:2。

cpu.cfs_period_us

以微秒(µs或者us)为单位,确定CPU资源分配的时间周期,与cpu.cfs_quota_us一起使用,来确定cgroup内进程所占有的单个CPU资源配额。比如总共1s时间之内cgroup中进程可以占用单个CPU资源为0.2s,则设置cpu.cfs_quota_us为200000,设置cpu.cfs_period_us为1000000。cpu.cfs_quota_us的上下限分别为1s和1000ms。

cpu.cfs_quota_us

指定了在一个周期之内cgroup中进程可以占用的CPU资源,以us为单位,周期由cpu.cfs_period_us确定。当组内进程使用完了分配的时间配额,他们会在当前的周期之内被节流,即处于throttled状态,在下一个调度周期内拥有新的时间配额运行。因为quota和period参数基于单个CPU,如果想要cgroup中进程完全使用两个CPUs,则可以设置quota信息为200000,而period信息为100000。如果设置cpu.cfs_quota_us为-1,则表示cgroup不受CPU的时间配额限制,对每个cgroup来说这是默认配置(root对应的cgroup除外)。

cpu.rt_period_us

仅用于实时调度进程,指定了实时进程CPU时间周期信息,以us为单位。

cpu.rt_runtime_us

仅用于实时调度进程,以微秒为单位指定cgroup中进程最长连续可以占用的CPU资源。设定该数值可以防止单个cgroup中进程占用整个CPU资源。实际可以占用的CPU资源会根据CPU数目成倍增加。比如设定cpu.rt_period_us为1000000,cpu.rt_runtime_us为200000,则在Multi-CPUs系统上cgroup中进程可以占用CPU时间为0.4s,而在4-CPUs系统上则为0.8s。

rt_runtime_us参数

配置到struct rt_schedulable_data结构的rt_runtime成员
rt_runtime成员引用的地方如下:

__sched_setscheduler

在设置sched的配置过程中,如果rt_policy开启,则对进程的task_group属性进行判断,如果其rt_bandwidth.rt_runtime为0,则设置失败,不能将实时进程放入rt_runtime为0的task_group中

#ifdef CONFIG_RT_GROUP_SCHED/** Do not allow realtime tasks into groups that have no runtime* assigned.*/if (rt_bandwidth_enabled() && rt_policy(policy) &&task_group(p)->rt_bandwidth.rt_runtime == 0 &&!task_group_is_autogroup(task_group(p))) {task_rq_unlock(rq, p, &flags);return -EPERM;}
#endif

sched_init

在初始化调度过程中设置rt_runtime成员,初始化发生在start_kernel中,在mm_init之后

rq->rt.rt_runtime = def_rt_bandwidth.rt_runtime;

cpu_rt_runtime_write

实际上为proc文件rt_runtime_us对应的写函数,依次调用sched_group_set_rt_runtime和tg_set_rt_bandwidth进行task_group的rt_bandwidth.rt_runtime属性设置,此处还调用了__rt_schedulable进行判断,来确定是否可以进行设定。判断过程为从root_task_group开始进行遍历循环,判断所有的task_group与其子task_group层级之间的rt_bandwidth信息是否合理,因现有存在的情况已经是合理的,只需要在循环过程中将task_group为当前task_group时对应的rt_bandwidth参数信息替换为准备设置的参数即可完成验证,如果没问题,则进行设置
用到了walk_tg_tree,在其中循环遍历所有group,完成tg_rt_schedulable的检查

深入解读Docker底层技术cgroup系列(4)——cgroup子系统cpu相关推荐

  1. Docker底层技术

    架构师之巅 1 容器 & Docker & 虚拟机 Container(容器)是一种轻量级的虚拟化技术,它不需要模拟硬件创建虚拟机.在Linux系统里面,使用到Linux kernel ...

  2. 你应当了解的Docker底层技术

    本文已获得原作者__七把刀__授权. Docker 容器技术已经发展了好些年,在很多项目都有应用,线上运行也很稳定.整理了部分 Docker 的学习笔记以及新版本特性,对Docker感兴趣的同学可以看 ...

  3. 长文解析:作为容器底层技术的半壁江山, cgroup如何突破并发创建瓶颈?

    简介: io_uring 作为一种新型高性能异步编程框架,代表着 Linux 内核未来的方向,当前仍处于快速发展中.阿里云联合 InfoQ 发起<io_uring 介绍及应用实践>的技术公 ...

  4. Docker 底层技术推导

    文章目录 1. 写在最前面 2. 什么推动了docker 出现 2.1 出现原因 2.2 优势总结 3. 大胆猜测一下实现 3.1 对比 Virtual Machine 3.2 实现 docker 需 ...

  5. 3-docker 架构和底层技术简介

    3-docker 架构和底层技术简介 Docker Platform Docker 是一个平台. 提供了一个开发.打包.运行app的平台 把app和底层 infrastructure 隔离开来 根据上 ...

  6. 实现容器的底层技术 - 每天5分钟玩转 Docker 容器技术(30)

    2019独角兽企业重金招聘Python工程师标准>>> 为了更好地理解容器的特性,本节我们将讨论容器的底层实现技术. cgroup 和 namespace 是最重要的两种技术.cgr ...

  7. mysql引擎层存储层_MySQL存储底层技术:InnoDB底层原理解读

    原标题:MySQL存储底层技术:InnoDB底层原理解读 存储引擎 很多文章都是直接开始介绍有哪些存储引擎,并没有去介绍存储引擎本身.那么究竟什么是存储引擎?不知道大家有没有想过,MySQL是如何存储 ...

  8. 精华推荐 | 【JVM深层系列】「GC底层调优系列」一文带你彻底加强夯实底层原理之GC垃圾回收技术的分析指南(GC原理透析)

    前提介绍 很多小伙伴,都跟我反馈,说自己总是对JVM这一块的学习和认识不够扎实也不够成熟,因为JVM的一些特性以及运作机制总是混淆以及不确定,导致面试和工作实战中出现了很多的纰漏和短板,解决广大小伙伴 ...

  9. 从概念到底层技术,一篇文解读区块链如何在企业中应用(下)

    本文分为上下两部分 猛戳回顾昨天精彩内容! 小锦推荐 近日,井通科技CEO武源文做客锦囊微课堂,围绕<区块链和大数据>一书,从四个方面综合阐述了区块链在智能经济时代如何与大数据无缝连接.课 ...

  10. 【容器底层技术】cgroup v2使用与测试

    cgroup v2使用与测试 1. 配置cgroup v2的环境 判断内核使用的cgroup版本 $ mount | grep cgroup cgroup2 on /sys/fs/cgroup typ ...

最新文章

  1. 微软开源数据处理引擎 Trill,每天可分析万亿次事件
  2. Sentinel实现限流,竟是如此的简单!
  3. Coding之路——重新学习C++(2):static的详细理解
  4. 在国外读phd 的时候和supervisor沟通的时候需要注意的点
  5. 近期有哪些值得读的推荐系统论文?来看看这份私人阅读清单
  6. 信息学奥赛一本通 1342:【例4-1】最短路径问题
  7. shell-script(command groups)
  8. 微信小程序相关项目实例集合
  9. linux 软件部署工具下载,linux配置 yum管理应用软件 、 快速部署Web/FTP
  10. 使用pt-query-digest进行日志分析
  11. VB.net 研华IO卡1762的编程方法 控件方法 VS2010专业版
  12. iredmail mysql_iRedmail配置手册
  13. 2021-05-15 随机生成车架号
  14. wincc安装服务器系统,wincc7.4安装硬件要求
  15. linux reboot故障
  16. linux生成了.swp文件怎么办
  17. Xilinx 7系列FPGA简介--选型参考
  18. windows mysql8安装_Windows上安装mysql8.0
  19. Redis第三话 – Springboot集成Redis以及常用API和客户端介绍
  20. Android微信智能心跳方案(转)

热门文章

  1. 《完整部署 OCS-NG》
  2. Oracle USE_LARGE_PAGES初始化参数
  3. 限流的简单使用及学习
  4. Linux安装jdk、删除Open jdk
  5. 开发环境、生产环境、测试环境的基本理解和区别
  6. 使用@Transactional(SUPPORTS)和不加@Transactional 有什么区别?
  7. AJAX初始化combox 并取值
  8. DataGridView - Column named XXX cannot be found
  9. 我的第二个切换图片高亮显示,给力
  10. js和jquery给iframe src赋值的3种方法