0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

BPF为内核编程提供了一个新的参考模型

Linux阅码场 来源:Linux阅码场 作者:Linux阅码场 2022-10-19 11:27 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

无论好坏,C语言已经是内核开发领域的通用语言了。Linux 内核的核心逻辑完全是用 C 语言编写的(加上一点汇编),它的驱动程序和 module 也是如此。虽然 C 语言因其强大而简单的语义而受到赞誉,但它是一种古老的语言,缺乏现代语言(如 Rust)中的许多特性。另一方面,BPF 子系统也提供了一个编程环境,工程师能够编写可以在内核空间安全运行的程序。在爱尔兰都柏林举行的 2022 年 Linux Plumbers Conference 上,Alexei Starovoitov 概述了 BPF 多年来的发展,为内核编程提供了一个新的参考模型。

BPF的使命

Starovoitov 首先描述了他对 BPF 的 "mission statement, 使命宣言":"创新、并启发大家创新"。内核中的编程历来是在两种情况下进行的:

core kernel 开发,包括主要的核心子系统,如内存管理、调度器、read-copy-update,等等。

kernel-module 开发,指的是构建那些不被编译到 main kernel image 里的内容,由 module loader 在后续加载。例如,驱动程序被写成一些内核 module,也有其他功能是这么做的,如文件系统、网络协议等等。

这是内核在很长一段时间内的状态,直到 3.15 版的内核中加入了最早版本的 extended BPF(eBPF)虚拟机。有了它之后,BPF program 可以用一个受到严格限制的 C 语言来编写,并被编译成 BPF 字节码,这将允许用户编写的代码可以经过验证确保安全,然后再在内核空间运行。

从那时起,BPF 在代码的规模、用户及贡献者社区的规模方面都稳步增长。根据 Starovoitov 的说法,BPF 邮件列表上每天都会收到 50-70 条信息,每月大约收到 2000 封邮件。平均每月里活跃贡献的 BPF 贡献者的数量也在同步增长,截至 2022 年 9 月,已达到约 140 人。目前来说,对 BPF 子系统的大部分贡献都不是来自 Meta BPF 小组了。

BPF编程环境

虽然大多数 BPF 程序是用 C 语言编写的,并用 LLVM Clang 编译器编译,但 BPF program 只是二进制 BPF 字节码对象文件,并未规定要用某种特定的语言来写。比如说,BPF 程序可以使用 Aya 来采用 Rust 编写,甚至可以直接用 BPF 汇编语言编写。也就是说,C是 BPF 程序的典型(canonical)编程语言;Starovoitov 的演讲继续概述了 BPF program 开发中 C 编程环境是如何演进的。

这个新的编程环境混合使用了 C 语言扩展以及运行时环境的组合实现的,这个运行时环境包含了 Clang、用户空间的 BPF 加载器库(libbpf)和内核中的 BPF 子系统。要想创建一个 BPF 程序,用户只要用 C 语言写一个程序,由 Clang 的 backend 实现来转换成 BPF 指令。在运行程序时,libbpf 将 BPF 程序加载到内存中,对程序进行重定位以使其可以跨平台以及不同的内核版本从而具备良好的可移植性,然后调用 kernel 来加载程序。最后在内核中,verifier 会采用静态方式验证该程序是否可以安全运行,然后启用之。

然而,BPF 的编程环境并不是一上来就这么丰富的。在 BPF 的早期,程序被要求使用 Starovoitov 所说的 "restricted C"。BPF 程序中的所有函数都必须完全是 inline 的,loop 循环、静态变量和全局变量以及内存分配都是不允许的。也没有类型信息(type information),所以 BPF 程序只能接收单一的、固定的 input context,用于 tracing 以及 network-filtering 相关功能。

尽管在这样一个高度限制性的环境中编写 BPF 程序也是很有用的,但很明显, BPF 所支持的使用场景还可以得到很大的扩展。其中一个扩展就是允许在 BPF 程序中使用静态函数。这样做需要使用 libbpf 在程序加载时对内核 BPF 程序进行重定位。经过多年的设计和尝试,最终也增加了对有限循环的支持,此外也支持了 iterator。

Extending the programming environment past full C

虽然这些使得 BPF 更接近于完整的 C 语言了,但最终可以看到,BPF 程序需要的一些功能甚至在完整的 C 语言标准中都没有。于是 BPF 社区开始扩展 BPF 编程环境,从而包括一些传统 C 语言没有的新特性。其中一个扩展功能就是 "一次编译-到处运行"(CO-RE, Compile Once - Run Everywhere)。

CO-RE 使 BPF 程序可以在不同的内核版本和平台上都可以运行。在 BPF 程序中,访问内核数据结构是很常见的行为。然而,内核没有为 struct layer 确保 ABI 不变,因此,如果内核结构在未来的版本或不同的 config 下发生了变化,在固定偏移的地方对内核结构进行读取的 BPF 程序可能就会读到错误的值。CO-RE 通过利用运行中的内核中的 BPF 类型格式(BTF)数据来解决这个问题。在加载一个程序时,libbpf 对所有的 struct 的访问都会进行重定位,以便根据当前运行的内核的 BTF 信息让被访问的字段的偏移量匹配上。

Starovoitov 还描述了 BPF 编程环境的其他一些有趣的新增功能。其中一个是 kptrs,它允许将内核内存的指针存储在 BPF map 中。另一个功能是允许程序在加载时访问内核 config 参数。内核 module 只能使用编译时设置的 config 值,但 BPF 程序在加载时可以根据当前内核的配置来决定自己的行为。还有一个特点是 "type tags",可以让程序能对变量进行 annotation,从而描述它们的使用方式。例如,kptrs 可以用 __kptr 和 __kptr_ref type tags 来进行标注,从而表明它们分别是 unreferenced 或者 referenced kptr。当然指针也可以用 __user 或 __percpu 标准,来告诉编译器和 verifier 这个指针分别指向用户内存或 per-CPU 内存。

Plans for the future

目前正在设计和实现更多的扩展,包括 lock-correctness 正确性验证,以及支持 BPF 程序包含 assertion。lock 的验证乍一看似乎是一个很难解决的问题,而 Dave Marchevsky 和 Kumar Kartikeya Dwivedi 都已经发出了 RFC patch set 来实现用于 lock 验证的新 map type。Marchevsky 的 patch set 提出了一个新的红黑树 map type,而 Dwivedi 的 patch set 提出了一个 list map type。这两个 patch set 都实现了共同的效果,允许 BPF 程序执行由 verifier 检查和验证过的 locking 机制。

assertion 验证仍处于规划阶段,实现起来可能会很复杂。assertion 将作为给编译器和 verifier 的信号,assertion 被用来指示程序中的一些不变的因素,这些不变因素的失败将导致程序中止。Starovoitov 声称,弄清如何让程序中止,这会是一个 "有趣" 的问题,因为它需要安全地对堆栈进行 unwind,调用 kptr destructor,以及其他收尾工作。

Starovoitov 在演讲的最后分享了他对 BPF 未来的观点:会取代内核模块成为扩展内核的有效方式。早期版本的 BPF 程序看起来更像是带有固定的 BPF helper function 和固定的 map type 的用户空间程序,而如今新的 BPF 已经可以让用户在更多个性化使用场景下对内核进行扩展。事实上,这样的使用场景已经在 upstream 社区被提出来了。在 Starovoitov 之后在 LPC 发言的 Benjamin Tissoires,一直在开发一个 patch set,希望用 BPF 程序来 fix 人类输入设备(HID)的 quirk。到目前为止,还没有一个内核 module 被 BPF 程序完全取代掉,不过,很期待看到内核的其他一些功能可以在 BPF 程序中实现。

一位听众要求了解 Starovoitov 所提到的 lock-correctness 验证的更多细节。Starovoitov 说,这个工作还在进行当中,但他乐观地认为可以找到一种方法来进行 static lock checking,从而验证数据保护是正确的,并保证不会发生死锁。Dave Miller 回应说,如果锁可以由 verifier 进行静态检查,那么可能可以研究一下 locking 逻辑是否可以由 verifier 自动生成。Starovoitov 回答说,这就是他们希望实现的目标,目前的设计中将 lock 和受保护的数据在同一次 allocation 中放在一起。对于不能跟 lock 放在一起的数据,可以用 BTF type tag 来指定它需要明确进行锁保护。

审核编辑 :李倩

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • C语言
    +关注

    关注

    183

    文章

    7642

    浏览量

    144612
  • 编程
    +关注

    关注

    90

    文章

    3707

    浏览量

    96765
  • 驱动程序
    +关注

    关注

    19

    文章

    868

    浏览量

    49958
  • BPF
    BPF
    +关注

    关注

    0

    文章

    26

    浏览量

    4633

原文标题:LWN:让BPF成为一个更安全的内核编程环境!

文章出处:【微信号:LinuxDev,微信公众号:Linux阅码场】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    IT岗位天塌了!Claude 4震撼发布:AI编程模型再进化

    Claude Opus 4 和 Claude Sonnet 4。这两模型旨在更好地遵循指令,在编写代码、解答复杂问题等任务中,能够更自主地运行。其中,Opus 4 堪称全球顶级编程模型
    的头像 发表于 05-26 07:52 5564次阅读
    IT岗位天塌了!Claude 4震撼发布:AI<b class='flag-5'>编程</b>大<b class='flag-5'>模型</b>再进化

    汽车HIL测试系统,欧美标充电模型Simulink模型,开发,有偿

    提供欧美标充电模型,交付物白盒Simulink模型
    发表于 09-04 16:23

    3Dfindit 提供的数字立方体模型研究项目的可视化提供支持

    作为学习项目的部分,罗伊特林根教育大学的学生们在比辛根集中营纪念地的博物馆中使用 3Dfindit 动画立方体模型进行了学习。作为历史教学研讨会的部分,学生们研究巴登-符腾堡州
    发表于 08-01 14:36

    FA模型访问Stage模型DataShareExtensionAbility说明

    DataShareExtensionAbility提供数据库的读写服务。 服务端由FA模型升级到Stage模型后,会导致FA模型的客户端在API 9(含)之后的版本上无法访问服务端。
    发表于 06-04 07:53

    如何将FA模型开发的声明式范式应用切换到Stage模型

    模型切换概述 本文介绍如何将FA模型开发的声明式范式应用切换到Stage模型,您需要完成如下动作: 工程切换:新建
    发表于 06-04 06:22

    KaihongOS操作系统FA模型与Stage模型介绍

    ,是目前主推且会长期演进的模型。Stage模型提供AbilityStage、WindowStage等类作为应用组件和Window窗口的“舞台”,因此称这种应用
    发表于 04-24 07:27

    如何基于Kahn处理网络定义AI引擎图形编程模型

    本白皮书探讨了如何基于 Kahn 处理网络( KPN )定义 AI 引擎图形编程模型。KPN 模型有助于实现数据流并行化,进而提高系统的整体性能。
    的头像 发表于 04-17 11:31 681次阅读
    如何基于Kahn处理网络定义AI引擎图形<b class='flag-5'>编程</b><b class='flag-5'>模型</b>

    获取具有三输出的自定义模型的输出张量,运行时错误是怎么回事?

    获取具有三输出的自定义模型的输出张量: 从 openvino.runtime 导入内核 内核 = 内核() model = core.re
    发表于 03-05 09:44

    RK3588开发板上部署DeepSeek-R1大模型的完整指南

    与OK3588-C开发板的深度融合,标志着国产AI大模型从云端向边缘端的延伸。这种“先进算法+定制化芯片”的协同模式,不仅解决边缘侧实时性、隐私保护等关键需求,更构建起从技术研发到产业赋能的完整价值链条,
    发表于 02-27 16:45

    【「基于大模型的RAG应用开发与优化」阅读体验】+第章初体验

    机制。 《基于大模型的RAG应用开发与优化》第章以清晰的逻辑框架,帮助读者建立对大模型与RAG的全局认知。通过剖析技术原理、优势与挑战,作者后续章节的实践内容奠定
    发表于 02-07 10:42

    中微推出7款计量方案,客户提供站式服务

    中微推出7款计量方案,客户提供站式服务测量芯片主要是中微RISC内核的高精度测量芯片,内置大容量的Flash,具有多级可编程放大器和差分
    的头像 发表于 01-14 15:03 838次阅读
    中微推出7款计量方案,<b class='flag-5'>为</b>客户<b class='flag-5'>提供</b><b class='flag-5'>一</b>站式服务

    中微推出5款计量方案,客户提供站式服务

    中微推出5款计量方案,客户提供站式服务前言测量芯片主要是中微MCS-51内核的高精度测量芯片,内置大容量的Flash,具有多级可编程放大
    的头像 发表于 01-10 18:58 693次阅读
    中微推出5款计量方案,<b class='flag-5'>为</b>客户<b class='flag-5'>提供</b><b class='flag-5'>一</b>站式服务

    【「具身智能机器人系统」阅读体验】2.具身智能机器人大模型

    。 多模态融合的创新与突破 机器人控制技术的另一个重要突破在于多模态大模型的应用。相比于仅通过文字进行人机交互的传统方法,现代机器人能够融合视觉、声音、定位等多模态输入信息,任务执行提供
    发表于 12-29 23:04

    AI模型部署边缘设备的奇妙之旅:目标检测模型

    智视觉模块上部署 PaddleDetection 模型如果说有自己制作数据的话,需要将数据上传,然后在修改全局配置项,修改数据集地址以及对应的类别数。 按照厂家提供的配置直接进行训练转换。 训练完成后,会自动生成
    发表于 12-19 14:33

    卡诺模型为人工智能领域提供种全新的视角

    在探索人工智能如何更深层次满足用户需求、提升用户体验的旅程中,卡诺模型(Kano Model)提供极具价值的理论框架。这
    的头像 发表于 12-11 10:17 946次阅读