苏乐-阿里云 2021-01-20 81浏览量
io_uring 作为一种新型高性能异步编程框架,代表着 Linux 内核未来的方向,当前仍处于快速发展中。本文先简单整理了各版本内核 io_uring 所支持特性,再介绍 io_uring 社区发展思路及当前社区在推进的几个比较有价值的特性,最后介绍阿里云内核存储团队围绕 io_uring 所开展的社区工作。
以下信息主要参考每个内核版本发布的 Release Notes,相关特性可参考 io_uring 三个系统调用的 man page 以获得更详细的信息。
Alibaba Cloud Linux 2 io_uring 特性基本上与社区主线 v5.8 版本保持同步,同时包含了我们推送中的特性,并在稳定性上进行了加固。
当前 io_uring 社区开发主要聚焦在以下几个方面。
特性增强
io_uring buffer registration 特性增强
io_uring 的 buffer registration 特性可以用来减少读写操作时频繁的 get_user_pages()/unpin_user_pages() 调用,get_user_pages() 主要用来实现用户态虚拟地址到内核页的转换,会消耗一定的 cpu 资源。来自 Oracle 的同学这组patchset 让 buffer registration 特性支持更新和共享操作,更加方便用户态编程,目前已发到第三版。我们遇到一些业务也明确提出过需要 buffer registration 支持更新操作。
https://lore.kernel.org/io-uring/d1d0d364-cd9b-9ded-aa0b-992e33569156@oracle.com/T/#t
fs/userfaultfd: support iouring and polling
来自 VMware 的同学这组 patchset 使得 userfaultfd 支持 io_uring,且支持 polling 模式。在RDMA,持久内存等高速场景,系统调用用户态内核态上下文切换的开销在 userfualtfd 整体开销的占比会非常突出,支持 io_uring 后,可以显著减少用户态内核态上下文切换,带来明显的性能提升。
https://lwn.net/Articles/838504/
add io_uring with IOPOLL support in scsi layer
io_uring 出现后,Linux 内核才真正完整地支持 iopoll,iopoll 相比于中断模式能带来明显的性能提升。此前只有nvme driver 对 iopoll 提供比较好的支持,现在 scsi 层也开始准备支持 iopoll。
https://patchwork.kernel.org/project/linux-block/patch/20201203034100.29716-2-kashyap.desai@broadcom.com/#23816967
no-copy bvec
在用 io_uring 进行 IO 栈性能分析时,来自 Facebook 的 Pavel Begunkov 发现在 direct IO 场景下是不需要拷贝bvec 结构的,他提交的这组 patchset 可以进一步提高内核 direct IO 的性能。
https://lore.kernel.org/lkml/cover.1609461359.git.asml.silence@gmail.com/
io_uring and Optane2
block 社区已经开始重视提高 IO 栈性能,一种思路是利用高性能设备,借助 io_uring 压测 IO 栈,从而发现软件性能瓶颈。比如 Intel提供最新的 Gen2 Optane SSD 给 block / io_uring 的维护者 Jens Axboe 来做内核 IO 栈性能分析。
https://lore.kernel.org/io-uring/4af91b50-4a9c-8a16-9470-a51430bd7733@kernel.dk/T/#u
fs: Support for LOOKUP_NONBLOCK / RESOLVE_NONBLOCK
Jens Axboe 优化 vfs 的文件查询逻辑,从而可以使 io_uring 的 IORING_OP_OPENAT 操作效率更高。
https://lore.kernel.org/linux-fsdevel/20201210200114.525026-1-axboe@kernel.dk/T/#m2057d72cb04a5e9e099375f94f26ca186e2d8835
IO 栈协同优化
借助 io_uirng 这一高性能异步编程框架,能比较容易地发现其他内核子系统的软件性能瓶颈,从而对其进行优化,以提高内核 IO 栈的整体性能。我们之前也基于这个思路发现了 block 层的几处优化,同时提出了 device mapper polling 打通的 RFC。
阿里云基础软件内核存储团队从 2020 年 2 月开始参与 io_uring 社区开发,目前累计贡献 40+ io_uring 内核补丁,10+ liburing 补丁,多项社区工作得到维护者 Jens Axboe的认可。主要涉及:
io_uring file registration 特性优化
io_uring file registration 特性用来减少文件操作时 fget / fput 原子操作开销。初始 file registration 特性实现在某些场景会导致其并不能减少 fget / fput 原子操作开销,我们采用一种比较巧妙的设计重构优化 io_uring 的 files registration 特性。前面介绍的 Oracle 同学在推进的 io_uring buffer registration 特性增强也用到了我们这种设计思路。
多 io_uring 实例共享 sqthread 特性
根据我们在业务场景的实践经验,在 io_uring 社区推进多 io_uring 实例共享同一个 sqthread 特性,在保证性能的前提下优化多实例 sqpoll 模式下的 cpu 开销。经过与社区的多轮讨论,社区最终也意识到该特性的业务价值,并在 5.10 内核版本中提供支持。我们后续又对该特性进行进一步重构优化,进一步改善性能。
io_uring_enter() 系统调用支持 timeout
初始的 io_uring 实现通过单独发送一个超时请求系统调用的方式来监测请求的超时情况,此方案在多线程环境使用时性能非常低。我们的方案只需要通过一个系统调用即可,相比于原有实现有着更好的性能,且用户态的编程友好。
io_uring 支持 EPOLLEXCLUSIVE 标记
采用该标记,可以有效的防止基于io_uring的网络应用出现惊群效应。
稳定性加固
我们主要将 io_uring 用于基于高速块设备的 IO 领域,利用 io_uring 的 sqpoll 和 iopoll 特性来加速内核 IO 性能。在实践过程中我们修复多个严重 BUG,如死锁,IO hang等。
内核其他子系统的协同
io_uring 本身只是一个异步编程框架,具体工作还是依赖 IO 栈上其他子系统。我们也积极对内核其他子系统进行优化,以更好的适配 io_uring。如 ext4 支持 iopoll,block split bio 场景 iopoll 协同等。
此外,我们目前还有一些重要工作处于社区推进中:
io_uring 目前仍然处于高速发展中,快速开发节奏较容易引入一些回归。目前上游社区功能回归测试基本依赖 liburing 自带的测试用例集覆盖,但性能回归测试仍然是空白。因此我们为 io_uring 开发了性能测试框架,以及时发现 io_uring 的性能回归。目前该项目已开源到 OpenAnolis 社区高性能存储技术 SIG。
此外,我们也积极探索了 io_uring 在网络应用上的优化,同时也开源到 OpenAnolis 社区,如 echo server benchmark,Redis,Nginx 等。欢迎对 io_uring 技术感兴趣的同学一起加入到 OpenAnolis 社区,围绕 io_uring 打造基于标准 Linux 内核的高性能 IO 栈。
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
集结各类场景实战经验,助你开发运维畅行无忧