写点什么

CPU 隔离:实践

  • 2022-04-06
  • 本文字数:3140 字

    阅读完需:约 10 分钟

CPU 隔离:实践

SUSE Labs 团队探索了 Kernel CPU 隔离及其核心组件之一:Full Dynticks(或 Nohz Full),并撰写了本系列文章:

 

1. CPU 隔离 – 简介

2. CPU 隔离 – Full Dynticks 深探

3. CPU 隔离 – Nohz_full

4. CPU 隔离 – 管理和权衡

5. CPU 隔离 – 实践

 

本文是第五篇。

 

我们通过前面四篇文章初步掌握了理论概念,现在终于到了实践阶段。本实践操作共配置了 8 个 CPU,将以完全隔离的方式在第 8 个 CPU 上运行一个无意义的用户空间循环,即:不受任何干扰。

内核配置要求


如果您运行的是 SUSE Linux Enterprise Server 15 SP3 (https://documentation.suse.com/sles/15-SP3/) 或更高版本,则无需担心这一问题;否则,一定要保证:

CONFIG_NO_HZ_FULL=y

CONFIG_CPUSETS=y

CONFIG_TRACING=y

 

第一条为在运行一个任务时停止 Tick 提供支持。第二条使任务绑定设置更容易。第三个选项支持对 CPU 隔离进行调试的跟踪能力。

引导要求


使用“nohz_full=” 引导参数,可以在运行单个任务时关闭计时器 Tick,并且大多数非内核负载也会迁移到隔离范围之外的 CPU。由于计划隔离第 8 个 CPU,我们需要通过以下信息引导内核:

nohz_full=7

 

CPU 编号从 0 开始,所以第 8 个 CPU 的编号为 7。此外,无需设置“rcu_nocbs=” 引导参数,如示例中通常显示的那样,nohz_full 可自动调节该参数。

任务绑定


有多种方法可以在隔离的任务和系统其余部分之间划分 CPU,首选方法是使用 cpuset (https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v1/cpusets.html)。对于有特殊需求的人,还有其他解决方案可用。


Cpuset


一旦内核启动,为了确保无关任务不会干扰 CPU 7,我们创建两个 cpusets 分区。名为“isolation” 的目录包含我们隔离的 CPU,它将来会运行隔离任务。另一个名为“housekeeping” 的目录承担常规负载。我们强制禁用“isolation” 分区的负载平衡,以确保任何任务都不能迁移进/出 CPU 7,除非手工移动。

 

在本例中,我们在 SUSE Linux Enterprise Server 15 SP3 上使用默认的 cpuset 挂载点(https://documentation.suse.com/sles/15-SP3/)


cd /sys/fs/cgroup/cpuset

mkdir housekeeping

mkdir isolated

echo 0-6 > housekeeping/cpuset.cpus

echo 0 > housekeeping/cpuset.mems

echo 7 > isolated/cpuset.cpus

echo 0 > isolated/cpuset.memse

cho 0 > cpuset.sched_load_balance

echo 0 > isolated/cpuset.sched_load_balance

while read P

do 

echo $P > housekeeping/cgroup.procs

done < cgroup.procs


对 housekeeping/cgroup.procs 的一些写入操作可能会失败,因为内核线程 pid 无法移出根 cpuset 分区。然而,未绑定的内核线程会自动强制绑定 nohz_full 范围之外的 CPU,因此可以安全地忽略这些故障。


Isolcpus


您还可以使用“isolcpus=” (https://www.suse.com/support/kb/doc/?id=000017747) 内核引导参数实现与以上 cpuset 设置相同的设置。但我们不建议使用这种解决方案,因为以后无法在运行时更改隔离配置。因此,尽管“isolcpus” 仍在使用,但一般“不推荐”。对于尚未支持 cpusets/cgroups 的专用或嵌入式内核,它可能仍然可用。


Taskset, sched_setaffinity(), …


从底层来讲,还可以使用 taskset(https://man7.org/linux/man-pages/man1/taskset.1.html) 等工具或者依赖 sched_setaffinity() (https://man7.org/linux/man-pages/man2/sched_setaffinity.2.html) 这样的 API,将每个任务绑定到所需的 CPU 集合。在不支持 cpuset 的系统中,其优点是允许在运行时更改绑定关系,这与“isolcpus” 不同;缺点是它需要更精细的工作。

IRQ 绑定


我们已经进行了任务绑定,但是硬件中断仍然可以在隔离的 CPU 上触发,并干扰其独占负载。所幸,我们可以通过 procfs (https://www.kernel.org/doc/html/latest/core-api/irq/irq-affinity.html)提供的接口安排在内务管理集上触发这些中断:


# Migrate irqs to CPU 0-6 (exclude CPU 7)

for I in $(ls /proc/irq)

do   

if [[ -d "/proc/irq/$I" ]]   

then       

echo "Affining vector $I to CPUs 0-6"

echo 0-6 > /proc/irq/$I/smp_affinity_list

fi

done


您可能会在其中一个中断向量上遇到 I/O 错误,例如 x86-64 机器上的数字 0,因为这是每个 CPU 上的计时器向量表,由于其本地性的特质,无法将其移开。然而,这个问题大可放心忽略,因为“nohz_full” 就是专门为解决这个问题而设计的。

防止其他干扰


在本例中,我们处理的是基于调度程序和中断的直接干扰。更高阶的话题将在后续文章中介绍,例如防止页面错误等异常(https://man7.org/linux/man-pages/man2/mlock.2.html)

实际测试


现在,大部分内务管理工作负载应在 CPU 0-6 上运行。CPU 7 将在无干扰的情况下运行用户空间代码。我们用启动器做一个无意义的循环。


虚拟用户空间循环


以下代码将当前任务绑定到隔离的 cpuset(即 cpu7),并始终执行一个死循环。它在启动并运行 10 秒后,最终被单独的启动器启关闭。


#include <stdio.h>

#include <fcntl.h>

#include <unistd.h>

#include <errno.h>

int main(void)

{   

// Move the current task to the isolated cgroup (bind to CPU 7)   

int fd = open("/sys/fs/cgroup/cpuset/isolated/cgroup.procs", O_WRONLY);

    if (fd < 0) {

        perror("Can't open cpuset file...\n");

        return 0;

    }

    write(fd, "0\n", 2);

  close(fd);

   // Run an endless dummy loop until the launcher kills us

    while (1)

        ;

       return 0;

}


将该代码包写在名为“user_loop.c” 的文件中,并编译:

 

$ gcc user_loop.c -o user_loop


启动器


除了在隔离的 CPU 7 上运行无意义的循环 10 秒之外,启动器的作用是跟踪可能对敏感工作负载有潜在干扰的事件。在本例中,我们使用 SUSE Linux Enterprise Server 15 SP3 上默认的跟踪 debugfs 装载点:


TRACING=/sys/kernel/debug/tracing/

# Make sure tracing is off for now

echo 0 > $TRACING/tracing_on

# Flush previous traces

echo > $TRACING/trace

# Record disturbance from other tasks

echo 1 > $TRACING/events/sched/sched_switch/enable

# Record disturbance from interrupts

echo 1 > $TRACING/events/irq_vectors/enable

# Now we can start tracingecho 1 > $TRACING/tracing_on

# Run the dummy user_loop for 10 seconds on CPU 7

./user_loop &

USER_LOOP_PID=$!

sleep 10

kill $USER_LOOP_PID

# Disable tracing and save traces from CPU 7 in a file

echo 0 > $TRACING/tracing_on

cat $TRACING/per_cpu/cpu7/trace > trace.7


这里跟踪到两个有意思的底层事件:


  • 调度程序上下文切换:报告任何抢占“user_loop” 的任务。这包括工作队列和内核线程。

  • IRQ 向量:报告任何(大多数)中断“user_loop” 的 IRQ,这包括计时器中断。

 

上述代码可以写入名为“launch” 的文件中,该文件与“user_loop” 位于相同的目录中。

完美世界的理想结果


在以 root 身份运行上述“launch” 之后,如果一切顺利,可以在“trace.7” 文件中找到以下内容:

 

<idle>-0 [007] d..2. 1980.976624: sched_switch: prev_comm=swapper/7 prev_pid=0

prev_prio=120 prev_state=R ==> next_comm=user_loop next_pid=1553

next_prio=120

user_loop-1553 [007] d.h.. 1990.946593: reschedule_entry: vector=253

user_loop-1553 [007] d.h.. 1990.946593: reschedule_exit: vector=253

 

在这里,user_loop 任务从时间戳 1980 秒处开始第一次跟踪,从 swapper(空闲任务)进行调度。然后,在 10 秒钟内(1990 – 1980),直到任务最终中断之前,任何事情都没有发生,这样做是为了处理发射器发送的关闭信号。这表明在这段时间内没有任务或中断干扰我们的 user_loop。

 

请注意:只有在完美世界中的完美机器上进行理想设置时,才会出现这种结果。

2022-04-06 12:073070

评论

发布
暂无评论
发现更多内容

网络设备日志接入观测云最佳实践

观测云

日志 网络设备

印记2024 | 20个“关键词”解码2024大型企业数智化

用友BIP

零代码 国产替代 用友BIP 中企出海 YonGPT

【YashanDB知识库】GBK库,生僻字插入nvarchar2字段后乱码问题

YashanDB

数据库 yashandb

豆包大模型家族全面升级,重磅发布视觉理解模型

Geek_2d6073

分布式系统架构2:服务发现

快乐非自愿限量之名

架构 分布式

只需几步,小白也能用 AI 做出精致社交名片!

豆包MarsCode

豆包MarsCode

Java程序员如何高效学习Spring Cloud Alibaba?

了不起的程序猿

微服务 架构师 SpringCloud java面试 springcloudAlibaba

全球首本关于动物干细胞的书籍,揭秘如何延长宠物寿命

财见

今日分享 | 带你领略可视化设计之美

inBuilder低代码平台

设计 可视化 可视化设计

面试官:DNS解析都整不明白,敢说你懂网络?我:嘤嘤嘤!

EquatorCoco

面试

集成自然语言理解服务,让应用 “听得懂人话”

不在线第一只蜗牛

人工智能

鸿蒙开发之不申请权限写入图片到相册

猫林老师

鸿蒙 HarmonyOS 鸿蒙应用开发 鸿蒙原生应用开发 HarmonyOS NEXT

Java程序员如何高效学习分布式系统设计?

了不起的程序猿

后端 分布式系统 架构师 分布式架构 java面试

微店API接口深度解析:如何高效获取商品详情及简短代码示例

代码忍者

微店商品详情API接口

监控报警服务RAM授权

DashVector

数据库 向量检索 大模型

思维导图怎么制作?这8个顶流软件值得推荐!

职场工具箱

效率工具 思维导图 在线白板 办公软件 思维导图软件

TaurusDB库表时间点极速恢复,大幅缩短数据恢复时间

华为云开发者联盟

数据库 数据恢复 :MySQL 数据库

购买GPU服务器后可以做什么?

Ogcloud

gpu 云主机 云服务器 GPU云服务器 云服务器租用

802.11ac IPQ4029 and IPQ4028 Qualcomm 'comprehensive Comparison of A Full Analysis

wifi6-yiyi

wifi5 11ac

安徽医科大学卫生管理学院与和鲸科技签署“101 数智领航计划”,共拓“医学+AI”学科建设与人才培养

ModelWhale

人工智能 大数据

一次天命之旅,见证科技自强

脑极体

AI

阿里巴巴1688 API接口深度解析:如何高效获取商品详情与关键词搜索商品数据

代码忍者

1688API接口

体育赛事直播平台功能开发与运营策略

软件开发-梦幻运营部

Python中构建全局字典的详细指南

EquatorCoco

Python

【YashanDB知识库】数据库一主一备部署及一主两备部署时,主备手动切换方法及自动切换配置

YashanDB

数据库 yashandb

【YashanDB知识库】删除用户组后,yasql不能免密登录问题

YashanDB

数据库 yashandb

【YashanDB知识库】崖山有哪些内存参数,Share Pool各个参数之间有什么关系

YashanDB

数据库 yashandb

鸿蒙开发之无须申请权限访问相册图片

猫林老师

鸿蒙 HarmonyOS 鸿蒙应用开发 鸿蒙原生应用开发 HarmonyOS NEXT

SD-WAN组网的四种方案及其差异

Ogcloud

SD-WAN SD-WAN组网 SD-WAN服务商 SDWAN SD-WAN国际专线

有灵AOP平台首届编程挑战赛开启在即!CCF程序员大会赠票福利限时派送中!

网易伏羲

编程 aop 网易伏羲

支持全量&增量迁移!YashanDB增量迁移实现原理解读

YashanDB

数据库 yashandb

CPU 隔离:实践_硬件_Frederic Weisbecker_InfoQ精选文章