LWN:BPF专用的内存分配器!

BPF性能分析—内存篇page_fault 性能分析—内存篇page_fault 分析步骤 1.sar -B 1整体分析,重点关注fault/s # sar -B 1 Linux 5.4.0-92-generic (zhangxa-Precision-3650-Tower-docker) 01/17/22 _x86_64_ (16 CPU) 11:35:37 pgpgin/s pgpgout/s fault/s majflt/s pgfree/s pgscank/s pgscand/s pgsteal/s %vmeff 阅读详情

关注了就能看到更多这么棒的文章哦~

A BPF-specific memory allocator

By Jonathan Corbet
June 30, 2022
DeepL assisted translation
https://lwn.net/Articles/899274/

内核现在并不缺内存分配器(memory allocator),所以人们可能不理解为什么又要加一个分配器。正如 Alexei Starovoitov 的这组 patch set 所表明的,BPF 子系统觉得就是有这个必要。其他提出的新的内存分配器目标是提高 BPF program 中进行内存分配的可靠性,毕竟 BPF program 可能的执行环境会是各种各样的。

在内核中分配内存总是很棘手的,哪怕是在最容易的情况之下。如果出现了分配请求不能立即被满足的情况,那么内存管理子系统根据当时的执行环境可能会有一些可以进一步采取的措施,也可能完全没有办法做什么。例如,可以通过将一些内存中的内容搬移到持久性存储设备中来释放这部分 memory,但是如果是某个文件系统正在申请内存,那么再使用该文件系统来写出数据就可能会导致死锁,因此这不是一个可行的措施。在内核中的许多场景下,不可能通过 sleep 来等待内存空闲出来。如果内核目前正在处理一个来自 CPU 的 non-maskable interrupt(NMI),那么能做的就更加少了。

大多数内核代码都是为了在一个特定的环境中运行而撰写的,并且它知道此时可用哪些内存分配选项;这些信息是通过分配请求中的 GFP flag 来传递给内存管理子系统的。当某个特定的函数需要在多个上下文中被调用的话,它通常就必须先假设它是在最严格的上下文中运行一样来进行内存分配;这对开发者来说是很不方便的。

近年来已经开发出一些像内存池("mempools")这样的机制,它会预先分配一定数量的内存,以确保在需要的时候可以直接使用,从而使开发者更轻松一些。很自然地,内存池很快产生了一个新的问题:内核开发者采用了内存池作为一种使自己免受内存分配失败影响的方式。不久之后,内核的大部分内存被捆绑在 mempools 中,无法用在实际需要内存的地方。这些年来人们在过度使用 mempool 以及无法在关键情况下分配内存之间已经找到了一个平衡点。

Mempools for BPF

BPF 程序可以在人们可以想象到的任意一个上下文中运行;尤其是针对 tracing program 来说更是如此。某个特定的 BPF program 可能被 attach 到一个在 atomic 上下文中运行的函数,从而来响应硬件中断,甚至是一个处理 NMI 的函数。这使得内存的分配成为一件不那么确定的事情,而这反过来又使 BPF verifier 的工作更加困难,verifier 的目的是确保 BPF program 在所有情况下都能表现良好。BPF 程序通常不直接分配内存,但它们可以间接地进行分配,例如,在 BPF map 中存储数据。这样的操作如果失败了就会造成不少后续麻烦。

patch 中提出的 BPF 专用分配器可以被认为是一种为 BPF 程序的需要而专门设计的 mempool。与 mempool 一样,其目的是在一个相对宽松的环境中创建一个放满了预分配内存的 cache 区,以便在条件变得更严格的时候可以随时使用这部分内存。虽然 mempool 的核心是一个由相同大小的可用 object 的列表组成的 cache 区,但这种 BPF cache 还是要更复杂一些。最少来说,针对系统中的每个 CPU,一个 BPF cache 由两个相同大小的 free object list 组成(一个用于大多数情况下的分配,另一个用于处理 NMI 时的分配)。而一个更复杂的变种方案就是每个 CPU 有 11 对 size 各不相同的 object list;也就是每个 CPU 有 22 个 free-object list。

其中的核心逻辑非常简单:当 BPF program 需要分配内存时,它就像调用 kmem_cache_alloc()(对于相同大小的 cache)或调用 kmalloc()(用在可变 size 的对象上)那样来从 cache 中分配。调用者申请的时候会把一个 free object 从当前 CPU 的相应 list 中移出来,并返回给调用者;只有在当时正在处理 NMI 的情况下,才会使用 NMI 专用的 list。在释放 object 的时候,它们会被返还到当前 CPU 的相应的 per-CPU list 中,这可能并不是它们之前被分配出来时的那个 CPU 了。这些操作是在禁用中断和 migration 的情况下进行的,所以它们进行的时候就可以不需要任何其他类型的 lock 了。假设 cache 没有被耗尽,那么 BPF program 就能够在任何上下文里面安全地进行内存分配。

当第一次建立 cache 时,在每一个普通 list 里面会最多放 4 个 object,并且每个 NMI 列表中会针对每个 size 来准备一个 object(当然是针对每个 CPU)。不过,每当从 list 中分配一个对象时,剩余可供分配的 object 的数量会跟一个低水位进行比较(也就是 32 个 object );如果低于这个值,就会使用 irq_work 机制来调用一个函数,将 list 扩展到 64 项。在非实时内核中,这项工作会是在内核线程中实现的,在那里内存分配相对来说不受太多限制。

同样,每当一个 object 被返回到 BPF 分配器时,list 的长度会与高水位(96 个)进行比较;如果 list 太长了,就会把一些 object 返回给内核,从而把数量减少到 64 个。这可以防止 cache 积累过多的 object;这部分代码还可以处理 object 在一个 CPU 上分配而在另一个 CPU 上 free 所导致的可能的不平衡问题。

Memory use

值得注意的是,这些 cache 并不是 global object;它们是为每个 user 所独立分配的。例如,为 BPF 程序使用的每一个 hash map 会建立一个 cache,会有很多这样的 hash map。因此,我们很自然地想知道,在一个繁忙的系统中,这些 cache 可能会消耗多少内存。上面描述的行为显然是为了使内存可以随时进行分配,同时限制 cache 本身的总内存使用量。正常来说,大多数用户不会在每个可用的 CPU 上都针对所有可能 size 都分配 object,而且大多数 object 也不会在响应 NMI 时运行。保留数百个 object 以备不时之需是很浪费的,所以 BPF 的 memory cache 会最少量的 object 数量来开始,每个 list 只有在该 list 发生了实际分配时才会填充更多 object 进来。

不过,还是需要担心这些 cache 是否会增长过多导致消耗了太多的内存,尤其是在有很多 cache 的时候。如果有 memory cgroup 的 limit 的话,cache 的分配也会被计算在内,但是对于专门用于 BPF cache 的内存并没有其他限制。如果内核发现自己需要其他地方的内存,也没有 shrinker 类型的机制可以减少 cache 的 size,并且也统计能显示当前有多少这样的 cache,或者目前有多少内存被分配给它们。

这个 patch set 增加的唯一使用位置就是 hash map 的实现代码;它会使用固定 size 的方式。不过,这里存在 kmalloc() 方式的选项,就说明还有其他的一些需要这种方式的代码在考虑近期也进来调用。

作为对邮件的回应,Christoph Hellwig 建议 Starovoitov 在继续工作之前先与现有的 slab allocator 的维护者进行一下讨论。不过到目前为止,内存管理开发者对这组 patch 的回应很少,所以不清楚他们对此事的想法。这个新的 allocator 完全包含在 BPF 代码中,不涉及内存管理子系统,所以原则上可以在没有他们参与的情况下进行开发与合入。不过,内存管理方面的开发人员在这个领域有一些专业知识,他们可能会对如何解决这个问题有一些有价值的想法。

全文完
LWN 文章遵循 CC BY-SA 4.0 许可协议。

欢迎分享、转载及基于现有协议再创作~

长按下面二维码关注,关注 LWN 深度文章以及开源社区的各种新近言论~

format,png

Obsidian的Git插件设置配置全流程 -- 简单的电脑端多平台同步方案及常见问题 Git同步obsidian的保姆级教程和常见问题 阅读详情

相关推荐

libfranka---joint_impendence_control例程分析

joint_impedance_control.cpp例程分析 部分内容来自链接,我个人以初学者的角度对代码进行了更加细致的解释。 核心部分: // Set and initialize trajectory parameters. const double radius = 0.05; const double vel_max = 0.25; const double acceleration_time = 2.0; const double run_time = 20.0; d

weixin_41567783的博客 1121

BMC缓存:基于eBPF的内核级缓存系统

BMC缓存:基于eBPF的内核级缓存系统 项目介绍 BMC(BPF Memory Cache)是为加速Memcached而设计的一款在Linux内核中运行的缓存解决方案。本项目源自NSDI'21的一篇论文,它利用安全的eBPF技术实现了一个复杂缓存服务,无需改动Linux内核或Memcached应用程序本身,即可广泛部署于现有系统。特别地,BMC针对类似Facebook的小规模请求进行了优化,提高...

gitblog_00658的博客 399

【浙大翁恺】C语言习题

/* 02-0. 整数四则运算(10) 本题要求编写程序,计算2个正整数的和、差、积、商并输出。 题目保证输入和输出全部整型范围内。 输入格式: 输入在一行中给出2个正整数A和B。 输出格式: 在4行中按照格式“A 运算符 B = 结果”顺序输出和、差、积、商。 输入样例: 3 2 输出样例: 3 + 2 = 5 3 - 2 = 1 3 * 2 = 6 3 / 2 =.

qq_43600867的博客 5853

BMC:加速Memcached的革命性内核缓存解决方案

BMC:加速Memcached的革命性内核缓存解决方案 项目介绍 BMC(BPF Memory Cache)是一款专为Memcached设计的内核级缓存系统,旨在通过安全的内核缓存和预堆栈处理技术,显著提升Memcached的性能。该项目基于NSDI'21论文《BMC: Accelerating Memcached using Safe In-kernel Caching and Pre-stac...

gitblog_00664的博客 606

睿尔曼超轻量仿人机械臂--机械臂接口介绍

本文介绍了睿尔曼超轻量仿人机械臂的控制器接口及末端接口。

realman_Rop的博客 3434

rk3568 rockit编译测试

编译rockit不能使用SDK默认编译kernel的交叉编译,需要采用编译buildroot的,而编译buildroot的编译器SDK并没有存放,需要编译过buildroot之后才可以用。命令参数相关解析可查阅代码,这里提醒一下-l参数,这是程序运行计数,默认是100,时间很短,基本上显示画面一闪而过,一度以为是程序哪里出问题了,改用-l 1000,画面显示时间加长。此处跳过系统,单领出来编译。rockit组件包在4.10版本需要手动编译,奈何我的版本怎么都编译不了,后来改用5.10版本才编译通过。

zfenggo的博客 4196

bpf-跟踪函数

通过bpf确认内存申请 1 #include<stdio.h> 2 #include<string.h> 3 int main(void) 4 { 5 int len = 1024*1024; 6 char *buf; 7 printf("pid=%d\n", getpid()); 8 getchar(); 9 malloc(len);

weixin_43690845的博客 345

Windows平台无人机仿真:从零搭建SITL环境与QGC联调

本文详细指导了在Windows平台上从零搭建无人机软件在环(SITL)仿真环境,并与QGroundControl(QGC)进行联调的完整流程。通过使用Cygwin工具链,开发者可以在没有实体硬件的情况下,模拟运行ArduPilot飞控,并通过MAVLink协议连接QGC地面站进行全功能测试,为无人机软件开发提供了一个安全、经济的虚拟沙盒环境。

weixin_29239279的博客 407

LWN:针对BPF代码的内存分配器!

关注了就能看到更多这么棒的文章哦~A memory allocator for BPF codeBy Jonathan CorbetFebruary 4, 2022DeepL assist...

Linux News搬运工 388

Deepseek接入QQ机器人:实现拟人化概率回复的完整指南

大语言模型API正在快速改变即时通讯工具的交互方式。通过标准化的OpenAI兼容接口,开发者可以将Deepseek等AI服务嵌入到QQ机器人等IM场景中,实现自然语言对话能力。其核心原理在于事件驱动架构:消息接收层通过OneBot协议获取群聊内容,业务层利用概率过滤与冷却机制控制回复节奏,再由大模型生成拟人化文本。这种设计不仅避免了机器人刷屏,还能通过系统提示词塑造性格,营造真实的社群陪伴体验。适用于粉丝群互动、内容订阅、小规模客服等场景,同时支持多群独立配置、关键词加权回复及上下文记忆扩展。在实际工程中,

weixin_29051245的博客 457

2025小红书跳转卡片实战指南:从零搭建独立后台与自动化发卡系统

本文提供了一份2025年小红书跳转卡片的实战搭建指南,详细解析了独立后台系统的核心架构与自动化发卡流程。文章从零开始,手把手教你使用Node.js、Vue.js等技术栈构建包含后台管理、用户制卡中心与前端交互的完整系统,旨在帮助运营者实现合规引流,并掌握数据自主权与自动化运营能力。

weixin_29234423的博客 516

LWN:保证可以分到连续内存的分配器!

保证 CMA 建立在 cleancache 之上,方法是在启动时分配一个物理上连续的内存区域,此时这种分配相对容易。不过,这些补丁相对较小,并且不会侵入未使用 CMA 的系统上的内存管理子系统,因此我们可能会看到超越内存应用程序在首次提出该想法大约 15 年后真正向前发展。如果内存可用,则可以快速分配。此后,大多数超越内存的工作都未被使用并已从内核中删除,但这个想法仍然存在,并且此补丁系列利用它来提供有保证的 CMA。多年来,人们付出了许多努力来避免对这种分配的需求,但在某些时候,它们是不可避免的。

Linux News搬运工 1592

华为OD机试真题 新系统2026-04-01 Java&Go 实现【勇攀数字高峰】

请你在给定的数字地形图中寻找登山路径,数字代表当前位置的海拔高度,要求从最低海拔出发,不断攀登,最终到达最高山峰。你需要寻找所有满足条件的登山路径。地图已经保证最低海拔和最高山峰都只有一个。

MISAYAONE的博客 612

LWN:BPF allocator 碰到麻烦了!

关注了就能看到更多这么棒的文章哦~The BPF allocator runs into troubleBy Jonathan CorbetApril 29, 2022DeepL assisted translationhttps://lwn.net/Articles/892743/5.18 内核合并的一个改动是为已经加载到内核里的 BPF 程序提供一个专门的内存分配器(...

Linux News搬运工 265

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

LWN:slab 分配器的sheaves以及任意上下文的分配功能!

总而言之,他说,来自 sheaves 层的初步结果是 promising(很有希望的),但它与 slab 调试的交互需要改进。(它是 slab 分配器的一部分)实现的工作会议,该版本期望可以从任何上下文中的 BPF 程序中调用。Hoang Nhat Pham 同意,他说他工作的系统具有大量的 CPU,但只有一个 NUMA 节点,从而导致大量的锁竞争,而 per-CPU 缓存可以改善这种情况。最后一个特性几乎是没有额外代价的,因为幸运的是,当请求到达时,分配器会有一个具有足够对象的 sheaf 存在。

Linux News搬运工 1708

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

LWN:SLUB分配器的下一步计划!

关注了就能看到更多这么棒的文章哦~What's next for the SLUB allocatorBy Jonathan CorbetMay 20, 2024LSFMM+BPFGemini-1.5-flash translationhttps://lwn.net/Articles/974138/Linux 内核中存在两个级别的基本内存分配器:页分配器 (page allocator),以页为单...

Linux News搬运工 465

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

LWN:MM 的多重奏(huge page, page promotion, KSM, BPF)!

它的页面扫描需要 CPU 时间,它需要进行一些繁琐的调整才能匹配工作负载,并且它会引发安全问题,因为它可用于确定系统中是否存在具有给定内容的页面。通常,这意味着将频繁访问的(“热(hot)”)数据放置在最快且最靠近使用它的工作负载的内存中,而将不太频繁访问的(“冷(cold)”)数据降级到较慢、更远的内存中。BPF 程序几乎可以在任何上下文中运行,包括在中断处理程序中,甚至在不可屏蔽中断(non-maskable interrupt, NMI)的处理程序中,在这些处理程序中,获取锁的能力受到严重限制。

Linux News搬运工 1577

LWN:优化只有一个用户的内存!

关注了就能看到更多这么棒的文章哦~Optimizing single-owner memoryBy Jonathan CorbetMay 26, 2023LSFMM+BPFDeepL assisted translationhttps://lwn.net/Articles/932391/内核里的内存管理子系统的主要优化目标是要能最大程度地共享资源。但是,正如 Pasha Tatashin 在 20...

Linux News搬运工 1095

LWN:要提供更好的 OOM 调试工具!

关注了就能看到更多这么棒的文章哦~Better tools for out-of-memory debuggingBy Jonathan CorbetMay 11, 2022LSFMMDeepL assisted translationhttps://lwn.net/Articles/894546/Out-of-memory(OOM)的情况是用户、系统管理员以及内核开发人...

Linux News搬运工 400

LWN: 6.1 合并窗口第一部分!

关注了就能看到更多这么棒的文章哦~The first half of the 6.1 merge windowBy Jonathan CorbetOctober 7, 2022DeepL assisted translationhttps://lwn.net/Articles/910312/6.1 合并窗口正在顺利进行中:自从窗口打开以来,已经有 5,752 个 non-merge changes...

Linux News搬运工 368

LWN:给kernel的swap添加一个抽象层!

关注了就能看到更多这么棒的文章哦~A new swap abstraction layer for the kernelBy Jonathan CorbetMay 23, 2024LSFMM+BPFGemini-1.5-flash translationhttps://lwn.net/Articles/974587/交换(swapping)在本质上可能是一种内存管理技术,但其实现也涉及内核的文件系...

Linux News搬运工 698

LWN:6.17 合并窗口的后半部分!

网络*:Qualcomm IPQ5018 内部 PHY、Airoha AN7583 MDIO 总线控制器、Broadcom 50/100/200/400/800 千兆以太网卡、Microchip Azurite DPLL/PTP/SyncE 设备以及 Realtek 8851BU 和 8852BU USB 无线网络 (Wi-Fi 6) 适配器。供电设备 (PSE) 实现增加了对可配置预算评估策略的支持,这些策略“被 PSE 控制器用于在功率预算超出等情况下决定首先关闭哪些端口”。详情请参阅 此合并消息。

Linux News搬运工 1800

LWN:针对可执行代码的另一个内存分配方案!

关注了就能看到更多这么棒的文章哦~Yet another memory allocator for executable codeBy Jonathan CorbetJune 8, 2023DeepL assisted translationhttps://lwn.net/Articles/933867/内核的代码越来越动态了,也就是随时会出现新的 text 段代码。目前,为新内核代码分配内存的责...

Linux News搬运工 1110

LWN:利用 __GFP_UNMAPPED 减少direct-map 碎片化!

关注了就能看到更多这么棒的文章哦~Reducing direct-map fragmentation with __GFP_UNMAPPEDBy Jonathan CorbetMarch 20, 2023DeepL assisted translationhttps://lwn.net/Articles/926020/内核的直接映射(direct map)使得 kernel 可以在自己的地址空间内...

Linux News搬运工 1035

LWN:回收未用的页表页的多种方法!

关注了就能看到更多这么棒的文章哦~Ways to reclaim unused page-table pagesBy Jonathan CorbetMay 9, 2022LSFMMDeepL assisted translationhttps://lwn.net/Articles/893726/内存管理子系统最重要的工作之一就是回收未使用(或很少使用)的内存,能够更好地利...

Linux News搬运工 332

LWN:Lua in the kernel!

关注了就能看到更多这么棒的文章哦~Lua in the kernel?By Jake EdgeSeptember 9, 2020Netdev原文来自:https://lwn.net/Ar...

Linux News搬运工 814
上一篇: LWN:2022年嵌入式Linux的进展!
下一篇: LWN:Ubuntu内核bug导致容器崩溃!
LinuxNews搬运工
博客等级 码龄7年 438粉丝 20原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值