cfs调度类深入解刨——RDT科普篇
上一篇《cfs调度类深入解刨——cfs任务状态统计细节篇》讲述了kernel中cfs任务阻塞、睡眠等统计逻辑及作用。本篇文章详细分析RDT的实现背景及设计方案。RDT设计方案资源控制resctrl的用户界面相关结构系列文章列表RDT在Linux内核 4.10版本中正式增加了对Intel RDT资源导向技术的官方原生支持并引入了专门用于操控RDT资源的resctrl虚拟文件系统。针对不同的内核演进阶段其配置与子功能增加的时间节点如下内核配置编译选项的演进随版本更新内核中开启RDT的编译宏Configuration Option发生过几次更名Linux 4.10 - 4.13 版本使用 CONFIG_INTEL_RDT_ALinux 4.14 版本更名为CONFIG_INTEL_RDTLinux 5.0 及至今为了兼容AMD的类似技术如 AMD Platform QoS该功能被抽象并彻底更名为 CONFIG_X86_CPU_RESCTRL。https://lwn.net/Articles/694800/具体子功能的加入版本Intel RDT是一个技术组合各子功能是分批次合入Linux内核的Linux 4.10首次加入支持基础的L3 CAT三级缓存分配和监测基础框架。Linux 4.12增加了MBA内存带宽分配支持。Linux 4.14通过resctrl文件系统正式支持CMT缓存占用监测和MBM内存带宽监测。Linux 4.16增加了L2 CDP二级缓存数据/指令隔离支持。Linux 4.18增加了高级的MBA软件控制器 (mba_sc)允许管理员直接以绝对值如MB/s限制带宽而不仅是百分比。设计方案在传统的多核处理器中OS可以通过进程调度很好地隔离CPU算力时间片通过虚拟内存很好地隔离内存空间物理地址。但是多个CPU核心之间共享的末级缓存LLC通常是L3 Cache和系统内存带宽Memory Bandwidth在硬件层面上是一个“大通铺”。这导致了一个致命问题“嘈杂邻居Noisy Neighbor效应”。一个高吞吐但对延迟不敏感的“流媒体/大数据”应用可能会疯狂刷新缓存并挤占带宽导致旁边一个极度敏感的“硬实时/数据库”应用的缓存被全部踢出引发性能剧烈抖动Tail Latency飙升。Intel RDTResource Director Technology资源导向技术的整体设计思路就是引入硬件级的“标签与配额”机制将原本不可控的共享资源变的可视、可控从而在硬件层面实现真正的多租户、多应用的服务质量QoS隔离。Intel RDT在硬件设计上不直接对“进程PID”或“内核线程”进行识别而是通过抽象出两个核心硬件ID作为连接“软件策略”与“硬件限制”的桥梁CLOSID (Class of Service ID服务等级标识符)控制标签硬件预设了有限个通常为8到32个服务等级。作用每个CLOSID对应一套资源分配规则比如CLOSID 1可以使用50%缓存CLOSID 2只能使用10%。RMID (Resource Monitoring ID资源监测标识符)监控标签硬件提供的更细粒度的计数器ID数量通常比CLOSID多得多。作用硬件通过RMID来独立统计不同业务实体的缓存占用量和内存带宽消耗。动态切换机制在CPU核心进行进程切换Context Switch时内核会读取当前进程绑定的rdtgroup并将其中的closid和rmid写入该核心的特定特征寄存器MSR_IA32_PQR_AS0xc8f。从此该核心发出的每一次内存请求都会携带这两个标签。Intel RDT将能力拆分为“监测Monitoring”和“控制Allocation”两个维度覆盖了缓存和内存两条主线CMT (Cache Monitoring Technology) - 缓存占用监测思路硬件根据请求携带的RMID在LLC内部进行细粒度的计数。价值让管理员知道“到底是谁用光了我的L3缓存”。CAT (Cache Allocation Tech) - 缓存分配技术思路引入CBM (Capacity Bitmask容量位图)。将L3缓存水平切分为若干个Bit如 111111111111 对应 12 个 Way。配置方式CLOSID 0 → 0xFFF (111111111111) → 可以使用100%缓存。CLOSID 1 → 0x00F (000000001111) → 只能使用低4位的缓存空间。高级模式 CDP (Code and Data Prioritization)将缓存进一步两分允许对代码段指令和数据段应用不同的位图。例如防止数据流的大规模读写把关键的动态链接库指令挤出缓存。MBM (Memory Bandwidth Monitoring) - 内存带宽监测思路统计每个RMID通过内存控制器IMC的本地Local和总Total物理内存流量。价值精确定位内存密集型Memory-bound应用。MBA (Memory Bandwidth Allocation) - 内存带宽分配思路在CPU核心与网格网络Mesh/Ring之间引入一个请求速率调节器Throttler。通过引入人工延迟Delay降低特定CLOSID向内存控制器发送请求的频率。内核增强 (mba_sc)原生硬件通常只支持百分比如限制到50%延迟级别。Linux内核在此基础上开发了软件控制器Software Controller通过MBM闭环反馈允许用户直接设定绝对值如10GB/s。在极度苛刻的实时计算中即使把缓存隔离出来CPU的正常驱逐机制Eviction仍可能因为某些突发读取将关键代码冲刷掉。RDT由此衍生出了伪锁定Pseudo-Locking思路圈地通过CAT划出一块独占的缓存片Way。锁死内核通过特殊的汇编指令如clflush结合prefetch把关键代码或数据强制拉入该缓存片然后关闭该片区的驱逐功能。效果这部分缓存直接变成了类似SRAM片上静态存储器极其快速且响应时间绝对固定绝对零Cache Miss带来的延迟抖动。Intel RDT的成功之处在于其软硬件协同的闭环设计资源控制resctrl的用户界面https://docs.kernel.org/filesystems/resctrl.html英特尔将此功能称为英特尔资源管理器技术Intel® RDT。AMD 将此功能称为AMD平台服务质量AMD QoS。此功能由CONFIG_X86_CPU_RESCTRL和x86 /proc/cpuinfo标志位启用名称标志RDT资源导向技术分配“rdt_a”CAT缓存分配技术“cat_l3”、“cat_l2”CDP代码和数据优先级“cdp_l3”、“cdp_l2”CQM缓存服务质量监控“cqm_llc”“cqm_ocup_llc”MBM内存带宽监控“cqm_mbm_total”“cqm_mbm_local”MBA内存带宽分配“mba”SMBA慢速内存带宽分配“”BMEC带宽监控事件配置“”ABMC可分配带宽监控计数器“”SDCIAE智能数据缓存注入分配强制执行“”通过“cat /proc/cpuinfo”查看是否支持以上特性如“cat /proc/cpuinfo | grep rdt_a”查看是否支持RDT分配。要使用此功能请挂载文件系统mount-t resctrl resctrl[-o cdp[,cdpl2][,mba_MBps][,debug]]/sys/fs/resctrl相关结构structrdtgroup{内核的资源控制resctrl子系统中直接对应用户空间挂载的/sys/fs/resctrl目录下的一个控制组CTRL Group或监测组MON Groupstructkernfs_node*kn;该资源组在 kernfs 虚拟文件系统中的节点structlist_headrdtgroup_list;系统中所有的rdtgroup实例串联成一个全局双向链表 u32 closid;类分配标识符Class of Service ID直接对应CPU硬件控制寄存器MSR的 ID。Intel/AMD处理器硬件只能识别有限个例如8个、16个或32个CLOSID。当某个CPU核心运行属于该 rdtgroup的进程时内核会将这个 closid 写入该核心的特定MSR寄存器硬件据此执行缓存或内存带宽的限制structcpumaskcpu_mask;记录当前属于该资源组的CPU掩码intflags;存储该组的运行期内部状态标志。例如RDT_DELETED标志。当用户rmdir删除一个目录时内核可能不会立刻销毁结构体因为还有进程在引用此时会先将flags标记为已删除阻止新进程加入atomic_twaitcount;等待机制引用计数保证多线程/多核并发访问时的安全。例如防止一个CPU正在读取该组的监控数据时另一个管理员线程并发将其删除enumrdt_group_typetype;标识该组的类型 主要分为两大类 RDTCTRL_GROUP控制组有独立的资源分配策略如特定的L3缓存大小 RDTMON_GROUP纯监测组作为控制组的子目录存在仅用来监控更细粒度的流量/缓存占用不涉及分配structmongroupmon;管理该组对应的硬件监测资源RMIDResource Monitoring ID。内嵌的mongroup结构体中包含硬件级的rmid。CPU硬件通过rmid来统计诸如LLC末级缓存占用量CMT以及内存总线带宽MBMenumrdtgrp_modemode;该资源组中缓存分配CAT的模式。 定义了缓存切片Bit级的共享与独占属性 RDT_MODE_SHAREABLE分配的缓存可以和其他组共享 RDT_MODE_EXCLUSIVE独占模式。此组分配的缓存切片其他任何组都不能占用用于极高实时性要求的场景 RDT_MODE_PSEUDO_LOCKED伪锁定模式enumresctrl_event_idmba_mbps_event;在开启高级内存带宽控制mba_sc软件控制器时指定要监控的事件类型。例如映射为QOS_MBM_LOCAL_EVENT本地内存带宽或 QOS_MBM_TOTAL_EVENT总内存带宽。内核的软件控制器会周期性读取该事件的带宽数据然后动态调整硬件的 MBA 限制级别以维持用户设定的绝对带宽上限如1000MB/sstructpseudo_lock_region*plr;指向内核**“伪锁定”Pseudo-locking**区域的指针。这是RDT技术的高级特性。当mode被设为伪锁定后内核会锁定一块特定的L3缓存使其永远不会被刷回内存。然后通过该指针管理该内存区域允许特定的极端低延迟应用如自动驾驶控制软件、硬实时通信直接将数据常驻L3缓存彻底消除了缓存未命中Cache Miss带来的延迟抖动。};structrftype{内核的资源控制resctrl子系统中structrftype是用于定义和构建控制组文件Resctrl Files的模板结构体。rftype 代表的就是/sys/fs/resctrl目录下自动生成的各个配置文件例如cpus、schemata、tasks和mode等char*name;定义该文件在用户空间显示的名称如schemata、tasksumode_tmode;定义该文件的标准 Linux 文件权限如0644代表读写0444代表只读conststructkernfs_ops*kf_ops;虚拟文件系统操作提供诸如open、release、mmap等更底层的VFS 回调。通常情况下标准的resctrl文件不需要直接实现这个字段而是留空并交由resctrl核心层统一提供通用的kernfs_ops然后再分发给下面介绍的seq_show和write回调unsignedlongflags;全局控制标志。用来决定该文件应该在哪些类型的目录中显示 RFTYPE_CTRL_BASE只在基础控制组CTRL Group目录中显示 RFTYPE_MON_BASE只在监测组MON Group目录中显示 RFTYPE_TOP_INFO只在全局根目录的 info/文件夹中显示unsignedlongfflags;功能依赖标志Feature Flags。用于根据当前CPU硬件实际支持的功能动态决定是否显示该文件。例如如果CPU支持L3 CAT带有RFTYPE_FFA_CMT标志的文件如监测数据文件才会被创建如果硬件不支持MBA相关的带宽配置文件就不会显示int(*seq_show)(structkernfs_open_file*of,structseq_file*sf,void*v);当用户在用户空间执行cat读取该文件内容时内核会触发这个回调用来输出多行、格式化的文本数据/* * write是一个通用的写入回调函数它直接对应于内核的写入操作并覆盖所有其他操作。最大写入大小由-max_write_len确定 */ssize_t(*write)(structkernfs_open_file*of,char*buf,size_tnbytes,loff_toff);用户执行 echoxxx修改配置时内核会触发这个回调内核在实现具体的write函数时会解析buf中的字符串如解析新的CPU掩码或缓存位图进行合法性检查然后更新对应的structrdtgroup结构并最终通过修改CPU的MSR寄存器将策略应用到硬件};系列文章列表《cfs调度类深入解刨——核心结构的用意》《cfs调度类深入解刨——核心结构细节分析》《cfs调度类深入解刨——最新内核细节分析1》《cfs调度类深入解刨——最新内核细节分析2》《cfs调度类深入解刨——最新内核细节分析3》《cfs调度类深入解刨——最新内核细节分析4》《cfs调度类深入解刨——最新内核细节分析5》《cfs调度类深入解刨——最新内核细节分析6》《cfs调度类深入解刨——MMU科普篇》《cfs调度类深入解刨——irq科普篇》《cfs调度类深入解刨——EAS科普篇》《cfs调度类深入解刨——clock科普篇》《cfs调度类深入解刨——HZ科普篇》《cfs调度类深入解刨——psi科普篇》《cfs调度类深入解刨——pelt细节篇》《cfs调度类深入解刨——cfs任务状态统计细节篇》