Block MQ Tag Set 硬件资源调度
- 请求会被提前分配到各个硬件队列上
- Tag Set 提供了 CPU 和硬件队列的映射
用户空间的 I/O 提交
传统的同步IO 提交方式
异步IO 提交方式(IO_uring)
- 通过
mmap
将队列结构映射到用户空间(减少拷贝) - 后端利用标准的系统调用(例如
readv
、writev
等等)
BIO
数据结构
BIO
是块层的一个IO 单元
BIO
是一个间接指针,它维护了用户要操作的数据在哪些物理位置,这样可以方便的进行切分(当队列受限的时候)或者复制(当一些数据要被拷贝到别的地方的时候)BIO
可以被合并,从而进行更大的提交请求,增大吞吐
硬件提交
提交
- 每个
BIO
会被链接到一个Request
里,然后根据它携带的软件上下文放到一个Request Queue
里,各个Request Queue
会被排队调度(内核线程)提交到硬件中(设备驱动)
完成
- 为了保持数据 CPU 本地化,中断应该绑定到相关 MQ 软件上下文的 CPU,否则就使用软中断重定向
- 设备驱动负责把完成的请求对应到相应的Request 上
- 根据完成了多少字节得到进度,请求可能需要被重新调度
bio
调用一系列回调,来通知内核线程/用户
块层的polling
polling
是Linux 内核的新特性,允许其使用轮训而非等待中断的方式来完成请求——可以减少时延并且减少高速设备由于中断引起的开销。使用时,发出 I/O 的应用线程或 io_uring 工作线程会主动在硬件队列中轮询发出的请求是否已完成
- 目前只支持NVMe 协议
- 设备驱动会为
polling
开一些关闭了中断的硬件队列 - 目前只支持应用层通过
DIRECT_IO
来使用polling
![[An Introduction to the Linux Kernel Block IO Stack.pdf]]