QCon北京「鸿蒙专场」火热来袭!即刻报名,与创新同行~ 了解详情
写点什么

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:073137

评论

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

从实验室到用户桌面,深度解析AI 落地实践之路

云智慧AIOps社区

人工智能 机器学习 AI 算法实践 智能运维AIOps

保利威荣获「年度最佳直播服务商」!引领视频直播行业创新发展

科技怪咖

从零到一,教你搭建「以文搜图」搜索服务(一)

Zilliz

人工智能 机器学习 深度学习

这三道MySQL面试题,99%的人答不出来!

程序员小毕

Java MySQL 数据库 程序员 面试

Kruise Rollout v0.2.0 版本发布:支持 Gateway API、StatefulSet 分批发布等能力

阿里巴巴中间件

阿里云 开源 容器 云原生 OpenKruise

打破数字化盐碱地:传统型企业如何踏稳数字化转型第一步

科技怪咖

秋招涨薪攻略!拿着GitHub标星80k的阿里性能优化笔记,把项目优化个遍

退休的汤姆

Java 阿里 社招 Java工程师 秋招

本周四晚19:00知识赋能第七期第3课丨OpenHarmony WiFi扫描仪实现

OpenHarmony开发者

OpenHarmony

“似水无形” 的小程序化技术

Speedoooo

小程序 小程序管理平台 轻应用 快应用 小程序平台

将 SAP Spartacus 作为 feature module 进行 Lazy Load 延迟加载时遇到的注入错误分析

汪子熙

typescript 前端开发 angular Spartacus 8月月更

2022年十大知名堡垒机品牌你真的知道吗?

行云管家

网络安全 数据安全 堡垒机 堡垒机品牌

阿里云 ACK 容器服务生产级可观测体系建设实践

阿里巴巴中间件

阿里云 容器 云原生 可观测

泰禾智能:智能改变未来,成就工业设备行业佼佼者

科技怪咖

Gitlab 中 Github import 功能存在远程代码执行漏洞

墨菲安全

业务出海必答题,融云全球通信网络技术挑战破解实践

融云 RongCloud

打造耳聪目明的MES系统,你准备好了吗?

科技怪咖

B站基于Iceberg+Alluxio助力湖仓一体项目落地实践

Alluxio

B站 iceberg Alluxio 湖仓一体 8月月更

SpringBoot 整合 数据库连接池(Druid、HicariCP、C3P0等等)

SpringBoot 2 Druid 8月月更

KusionStack 在蚂蚁集团的探索实践 (上)

SOFAStack

开源 技术分享 蚂蚁集团 Kusion kusionstack

打补丁是什么意思?如何快速对云主机批量打补丁?用什么软件?

行云管家

运维 云主机 IT运维 打补丁

浅谈 malloc 函数在单片机上的应用

矜辰所致

malloc 内存管理 8月月更

KubeEdge边缘计算在顺丰科技工业物联网中的实践

华为云开发者联盟

云计算 云原生 工业物联网 顺丰

RT-Thread记录(十四、I/O 设备模型之ADC设备)

矜辰所致

RT-Thread 8月月更 ADC

马蹄链Dapp系统开发部署技术

薇電13242772558

dapp

1 分钟在 Serverless 上部署现代化 Deno Web 应用

阿里巴巴中间件

阿里云 Serverless 云原生

激动!开启轻量化虚拟直播时代!

IT资讯搬运工

计费准确率高达100%,是如何实现的?

科技怪咖

105份墨天轮“国产化迁移”干货文档汇总(含TiDB、openGauss、上云等)

墨天轮

数据库 阿里云 TiDB 国产数据库 达梦

左邻云安全 | 全程守护,让园区安全看得见

科技怪咖

MobTech ShareSDK Android端微信分享小程序

MobTech袤博科技

微信小程序 android sdk

Docker下Prometheus和Grafana三部曲之一:极速体验

程序员欣宸

Grafana Prometheus 8月月更

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