操作系统与存储:解析Linux内核全新异步IO引擎io

在初始化完成之后,应用程序就可以使用这些队列来添加IO请求,即填充SQE。当请求都加入SQ后,应用程序还需要某种方式告诉内核,生产的请求待消费,这就是提交IO请求,可以通过io_uring_enter系统调用。

内核将SQ中的请求提交给Block层。这个系统调用既能提交,也能等待。

具体的实现是找到一个空闲的SQE,根据请求设置SQE,并将这个SQE的索引放到SQ中。SQ是一个典型的ringbuffer,有head,tail两个成员,如果head==tail,意味着队列为空。SQE设置完成后,需要修改SQ的tail,以表示向ringbuffer中插入了一个请求。

先从参数上来解析

2.如果flags中设置了IORING_ENTER_GETEVENTS,并且min_complete>0,这个系统调用会一直block,直到min_complete个IO已经完成才返回。这个系统调用会同时处理IO收割。

3.另外的,IORING_SQ_NEED_WAKEUP可以表示在一些时候唤醒休眠中的轮询线程。

staticintio_sq_thread(void*data)即内核轮询线程。

同样地,可以用这个系统调用等待完成。除非应用程序,内核会直接修改CQ,因此调用io_uring_enter系统调用时不必使用IORING_ENTER_GETEVENTS,完成就可以被应用程序消费。

io_uring提供了submissionoffload模式,使得提交过程完全不需要进行系统调用。当程序在用户态设置完SQE,并通过修改SQ的tail完成一次插入时,如果此时SQ线程处于唤醒状态,那么可以立刻捕获到这次提交,这样就避免了用户程序调用io_uring_enter。如上所说,如果SQ线程处于休眠状态,则需要通过使用IORING_SQ_NEED_WAKEUP标志位调用io_uring_enter来唤醒SQ线程。

以io_iopoll_check为例,正常情况下执行路线是io_iopoll_check->io_iopoll_getevents->io_do_iopoll->(kiocb->ki_filp->f_op->iopoll).在完成请求的操作之后,会调用下面这个函数提交结果到cqe数组中,这样应用就能看到结果了。这里的io_cqring_fill_event就是获取一个目前可以写入到cqe,写入数据。这里最终调用的会是io_get_cqring,可以见就是返回目前tail的后面的一个。

更详细的内容可以直接参考io_uring_enter(2)的manpage。

io_iopoll_complete实现

io_get_cqring实现

IO收割

来都来了,搞点事情吧,在我们提交IO的同时,使用同一个io_uring_enter系统调用就可以回收完成状态,这样的好处就是一次系统调用接口就完成了原本需要两次系统调用的工作,大大的减少了系统调用的次数,也就是减少了内核核外的切换,这是一个很明显的优化,内核与核外的切换极其耗时。

当IO完成时,内核负责将完成IO在SQEs中的index放到CQ中。由于IO在提交的时候可以顺便返回完成的IO,所以收割IO不需要额外系统调用。

如果使用了IORING_SETUP_SQPOLL参数,IO收割也不需要系统调用的参与。由于内核和用户态共享内存,所以收割的时候,用户态遍历[cring->head,cring->tail)区间,即已经完成的IO队列,然后找到相应的CQE并进行处理,最后移动head指针到tail,IO收割至此而终。

所以,在最理想的情况下,IO提交和收割都不需要使用系统调用。

高级特性

此外,我们可以使用一些优化思想,进行更进一步的优化,这些优化,以一种可选的方式成为io_uring的其它一些高级特性。

优化思想

非关键逻辑上提至循环外,简化关键路径。

优化实现

fixed_file_data结构

io_sqe_files_register实现FixedFiles操作

优化思想也是将非关键逻辑上提至循环外,简化关键路径。

如果应用提交到内核的虚拟内存地址是固定的,那么可以提前完成虚拟地址到物理pages的映射,将这个并不是每次都要做的非关键路径从关键的IO路径中剥离,避免每次I/O都进行转换,从而优化性能。可以在io_uring_setup之后,调用io_uring_register,使用IORING_REGISTER_BUFFERS操作码,将一组buffer注册到内核(参数是一个指向iovec的数组,表示这些地址需要map到内核),最终调用io_sqe_buffer_register,这样内核在注册阶段就批量完成buffer的一些基本操作(减小get_user_pages、put_page开销,提前使用get_user_pages来获得userspace虚拟地址对应的物理pages,初始化在io_ring_ctx上下文中用于管理用户态buffer的io_mapped_ubuf数据结构,map/unmap,传递IOV的地址和长度等),之后的再次批量IO时就不需要重复地进行此类内存拷贝和基础信息检测。

io_mapped_ubuf结构

io_sqe_buffer_register实现FixedBuffers操作

状态从未完成变成已完成,就需要对完成状态进行探测,很多时候,可以使用中断模型,也就是等待后端数据处理完毕之后,内核会发起一个SIGIO或eventfd的EPOLLIN状态提醒核外有数据已经完成了,可以开始处理。但是,中断其实是比较耗时的,如果是高IOPS的场景,就会不停地中断,中断开销就得不偿失。

我们可以更激进一些,让内核采用PolledIO模式收割块设备层请求。这在一定的程度上加速了IO,这在追求低延时和高IOPS的应用场景非常有用。

io_uring_enter通过正确设置IORING_ENTER_GETEVENTS,IORING_SETUP_IOPOLL等flag(如下代码设置IORING_SETUP_IOPOLL并且不设置IORING_SETUP_SQPOLL,即没有使用SQ线程)调用io_iopoll_check。

io_iopoll_check开始poll核外程序可以不停的轮询需要的完成事件数量min_complete,循环内主要调用io_iopoll_getevents。

io_iopoll_getevents调用io_do_iopoll。

io_do_iopoll中的kiocb->ki_filp->f_op->iopoll,即blkdev_iopoll,不断地轮询探测确认提交给Block层的请求的完成状态,直到足够数量的IO完成。

KernelSidePolling

IORING_SETUP_SQPOLL,当前应用更新SQ并填充一个新的SQE,内核线程sq_thread会自动完成提交,这样应用无需每次调用io_uring_enter系统调用来提交IO。应用可通过IORING_SETUP_SQ_AFF和sq_thread_cpu绑定特定的CPU。

小结

如上可见,内核提供了足够多的选择,不同的方案有着不同角度的优化方向,这些优化方案可以自行组合。通过合理地使用,可以使io_uring全速运转。

正如前文所说,简单并不一定意味着易用——io_uring的接口足够简单,但是相对于这种简单,操作上需要手动mmap来映射内存,稍显复杂。为了更方便地使用io_uring,原作者JensAxboe还开发了一套liburing库。liburing库提供了一组辅助函数实现设置和内存映射,应用不必了解诸多io_uring的细节就可以简单地使用起来。例如,无需担心memorybarrier,或者是ringbuffer管理之类等。上文所提的一些高级特性,在liburing中也有封装。

核心数据结构

liburing中,核心的结构有io_uring、io_uring_sq、io_uring_cq

核心接口

主要流程

核心实现

io_uring_queue_init的实现,前文已略有提及。其中的操作主要就是io_uring_setup和io_uring_queue_mmap,io_uring_setup前文已解析过,这里主要看io_uring_queue_mmap。

io_uring_queue_mmap初始化io_uring结构,然后主要调用io_uring_mmap。

io_uring_mmap初始化io_uring_sq结构和io_uring_cq结构的内存,另外还会分配一个io_uring_sqe结构的数组。

具体例程

如下是一个基于liburing的helloworld示例。

更多的示例可参考:

如上,推演过了设计与实现,回归到存储的需求上来,io_uring子系统是否能满足我们对高性能的极致需求呢?这一切还是需要profile。

测试方法

io_uring原作者JensAxboe在fio中提供了ioengine=io_uring的支持,可以使用fio进行测试,使用ioengine选项指定异步IO引擎。

可以基于不同的IO栈:

可以基于一些硬件之上:

测试过程中主要4k数据的顺序读、顺序写、随机读、随机写,对比几种IO引擎的性能及QoS等指标

io_uringpollingmode测试实例:

测试结果

网上可以找到一些关于iouring的性能测试,这里列出部分供参考:

主要有以下几个测试结果

从测试中,我们可以得出结论,在存储中使用io_uring,相比使用libaio,应用的性能会有显著的提升。

在同样的硬件平台上,仅仅更换IO引擎,就可以带来较大的提升,是很难得的,对于存储这种延时敏感的应用而言十分宝贵。

io_uring的优势

事物的发展是一个哲学话题。前文阐述了io_uring作为一个新事物,发展的根本动力、内因和外因,谨此简述一些可预见的未来的发展方向。

普及

应用层多使用。目前主要应用在存储的场景中,这是一个不仅需要高性能,也需要稳定的场景,而一般来说,新事物并不具备“稳定”的属性。但是io_uring同样也是稳定的,因为虽然io_uring使用到了若干新概念,但是这些新的东西已经有了实践的检验,如eventfd通知机制,SIGIO信号机制,与AIO基本相似。它是一个质变的新事物。

就我们腾讯而言,内核使用tlinux,tlinux3基于4.14.99主线;tlinux4基于5.4.23主线。

所以,tlinux3可以用nativeaio,tlinux4之后已经可以用nativeio_uring。

相信通过大家的努力,正如前文所说的PostgreSQL使用彼时新接口pread,Nginx使用彼时的新接口AIO一样,通过使用新街口,我们的工程也能获得巨大收益。

优化方向

降低本身的工作负载

持续降低系统调用开销、拷贝开销、框架本身的负载。

重构

追求真理的人不可避免地追求永恒。“政治只是一时,方程却是永恒。”——爱因斯坦如是说,时值以色列的第一任总统魏兹曼于1952年逝世,继任首相古理安建议邀请爱因斯坦担任第二任总统。

难免纰漏,欢迎交流,可以通过以下网址找到本文。

ComputerSystems:AProgrammer'sPerspective,ThirdEdition

AdvancedProgrammingintheUNIXEnvironment,ThirdEdition

TheLinuxProgrammingInterface:ALinuxandUNIXSystemProgrammingHandbook

UnderstandingNginxModulesDevelopmentandArchitectureResolving(SecondEdition)

THE END
1.《操作系统设计与实现:基于LoongArch架构》:带领学生全面剖析操作经过几年的实践,周庆国教授及带领的教学团队在基于LoongArch架构的教学版操作系统MaQueOS为主线进行的教学成果及经验上,成功编著了《操作系统设计与实现:基于LoongArch架构》一书。该书能带领学生全面剖析一个具备基本功能的操作系统内核的设计与https://mp.weixin.qq.com/s?__biz=MzA4MjU5NzkyNA==&mid=2688790552&idx=8&sn=3e6f2ee51c56d8d72aef14f611f5f8c9&chksm=bb97284ffe769772df2fec001ae5a84f65c59ec440b9583b1296ec6fe7c335eefc2edc50ed51&scene=27
2.操作系统设计与实现(豆瓣)大学计算机教育国外著名教材系列(影印版)(共42册), 这套丛书还有 《UNIX网络编程卷2》《计算复杂性》《自动机理论语言和计算导论(第2版影印版)》《数据结构》《分布式系统原理与范型》 等。 喜欢读"操作系统设计与实现"的人也喜欢的电子书· ··· 支持Webhttps://book.douban.com/subject/3108799/
3.操作系统设计与实现(第3版下册)中文PDF版21.8MB电子书下载《操作系统设计与实现(第3版 下册)》是关于操作系统的权威教材,详细探讨了操作系统的基本原理,包括进程、进程间通信、信号量、管程、消息传递、调度算法、输入/输出、死锁、设备驱动程序、存储管理、调页算法、文件系统设计、安全和保护机制等。大多数关于操作系统的图书均重理论而轻实践,而《操作系统设计与实现(第3https://www.jb51.net/books/483826.html
4.操作系统设计与实现第二版中文.pdf操作系统设计与实现(Minix系统中文版).7z 浏览:2 本书是一本操作系统教程,主要写了minix系统的设计和实现以及编译方法 ESP8266 官方全部开发文档资料打包下载 2021最新版 浏览:33 5星 · 资源好评率100% 10. **20b-esp8266_rtos_sdk_api_reference.pdf**:ESP8266实时操作系统(RTOS) SDK API参考文档,包含了EShttps://download.csdn.net/detail/zhilin_tang/7700045
5.《操作系统设计与实现(第三版)(上册)》(AndrewS.Tanenbaum(美当当网图书频道在线销售正版《操作系统设计与实现(第三版)(上册)》,作者:Andrew S. Tanenbaum(美)安德鲁 S. 塔嫩鲍姆 等著,出版社:电子工业出版社。最新《操作系统设计与实现(第三版)(上册)》简介、书评、试读、价格、图片等相关信息,尽在DangDang.com,网购http://product.dangdang.com/23727594.html
6.操作系统设计与实现(第一章引论操作系统概念)《Operating Systems: Design andImplementation Second Edition操作系统设计与实现 (第二版)安德鲁.坦尼鲍姆(Andrew S. Tanenbaum)阿尔伯特.伍德豪尔(Albert S. Woodhull)》 典型的操作系统由四部分构成:进程管理,I/O设备管理,存储器管理和文件管理。 第一章 引论 https://www.jianshu.com/p/3d270296e576
7.操作系统设计与实现:第3版操作系统设计与实现 作者:陈文智 ISBN:9787040467529 出版社:高等教育出版社 出版年:2017 现代操作系统(原书第3版) 作者:(荷)塔嫩鲍姆(Tanenbaum,A.S.)著 出版社:机械工业出版社 出版年:2009 Operating Systems:Design and Implementation 3rd = 操作系统:设计与实现 第三版(影印版) 作者:S.Tanenbaum,Andrehttps://www.las.ac.cn/front/book/detail?id=f5d81099a262db34c86eb97b5587da07
8.操作系统原理实现与实践作者似乎要表达一个意思:一个操作系统,是由它的设计者和用户共同决定的,之前和深信服面试官聊,说到为什么深信服是以用户为中心,面试官说,设计者们只能设计一个框架,细节还需要由用户来填充,这本书就体现了这一点。 作者似乎还想表达一点,操作系统,是附着在计算机硬件上的,所以操作系统的任务是更好地利用硬件,所以https://zhuanlan.zhihu.com/p/658808396
9.操作系统的设计与实现20240406002241.pdf操作系统的设计与实现.pdf,操作系统的设计与实现 一、引言 操作系统是计算机系统的核心部分,负责管理和控制计算机系统的硬 件和软件资源。它负责分配任务、管理内存、处理文件系统、控制设 备驱动程序等。本文将介绍操作系统的设计和实现。 二、操作系统设计 1、需求分析:https://max.book118.com/html/2024/0406/5111140131011134.shtm
10.一个64位操作系统的设计与实现至于软件方面,只要熟练运用汇编语言和C语言就足够编写操作系统了。 汇编语言主要用于控制和配置处理器,例如引导启动处理器、配置处理器运行状态、进程切换、中断和异常处理程序、设备I/O端口操作等必须操作寄存器的工作,或者是对性能要求极为苛刻的场景,这些工作C语言几乎无法实现。 https://www.ituring.com.cn/book/tupubarticle/26322
11.操作系统设计与实现pdf下载操作系统设计与实现第三版p软件介绍软件截图相关文章网友评论下载地址 小编为您推荐:操作系统设计与实现操作系统操作系统设计与实现第三版pdf高清版是计算机科学届非常有名的教材,在这里用户可以通过这本辅导教材,学习详细的操作系统基础知识,以及作者对于操作系统的不同见解,计算机专业的学生必备教材,欢迎有需要的用户来IT猫扑下载! 作者介绍 Andrewhttps://www.itmop.com/downinfo/340861.html
12.操作系统底层架构与内核设计及实现原理51CTO博客这是一段进行相加的操作,程序启动,在经过编译解析后会由操作系统把硬盘中的程序复制到内存中,示例中的程序是将123和456执行相加操作,并将结果输出到显示器上。由于使用机器语言难以描述,所以这是经过翻译后的结果,实际上每个指令和数据都可能分布在不同的地址上,但为了方便说明,把组成一条指令的内存和数据放在了一https://blog.51cto.com/u_11837698/6237152
13.基于Linux操作系统和ARM926EJ系统以CMOS图像通道为诊断网像的传输通道,将采集的超声图像信息送人系统总线,在嵌入式Linux操作系统平台上,实现了诊断图像的实时显示和静态图像的大容量非易失性存储,所实现的诊断系统不仅功能强大、扩展容易,而且还兼顾了小型化的需求。 2、 系统构架 本文设计的便携式超声诊断仪系统结构如图l所示。用户通过输入设备https://m.elecfans.com/article/1179009.html
14.基于Petalinux的Socket网络通信系统设计与实现AET基于Petalinux的Socket网络通信系统设计与实现 摘要:介绍了一款针对MicroBlaze软核处理器特别开发的嵌入式操作系统Petalinux,成功地实现了其在ML402开发板上的移植,并且在该系统上实现了基于TCP/IP协议的套接字接口Socket的网络通信。 关键词:FPGA;MicroBlaze软核处理器;Petalinux移植;Socket网络通信http://www.chinaaet.com/article/188921
15.网络工程专业人才培养方案(2022)3. 工程基础知识。掌握从事网络工程专业所需的数字电路与逻辑设计、计算机组成原理、程序设计、算法与数据结构、软件工程概论、数据库原理与技术等基础知识。 4. 网络工程专业知识。掌握从事网络工程专业所需的计算机网络原理与技术、操作系统、信息安全导论、物联网技术基础、网络安全技术、网络互连技术、无线网络技术、网https://www.csust.edu.cn/jtxy/info/1148/20900.htm