[ATC'19] Asynchronous I/O Stack: A Low-latency Kernel I/O Stack for Ultra-Low Latency SSDs

Intro

优化I/O的方法

  • 用户层面直接调用外部存储设备,需要应用包含文件系统的调用,臃肿,同时不同应用和用户间的冲突问题。
  • 优化操作系统内核的I/O 栈
    • 使用轮询来减少上下文切换的开销
    • 在底层减少一半的中断处理
    • 分散I/O指令
    • I/O block调度机制

Related Work

减少内核的开销

  • 减少中断处理的后半部分
  • 是用轮询技术而非中断,减少上下文切换
  • 混合轮询
  • 基于SSD的闪存随机读写简化调度策略
  • 在NVMe固件中进行调度
  • 对高优先级的任务,提供不同的IO path支持,最小化IO path的开销

修改存储接口

  • 分散/分散 IO合并多个IO到一个指令,减少往返次数
  • 移除doorbell机制和完成信号

改善fsync

  • 冲fsync请求发出到收到response,延长数据持久化的时间
  • 在日志提交记录中使用校验和,有效的重叠日志写入和块写入
  • 提出写守序系统调用,重叠的fsync效果相同,当应用需要使用fsync时,关于IO的操作将同步进行

用户层直接访问外设,存在隔离、保护等安全问题

Motivation

背景

现状:

  • I/O 请求过程中太多的步骤
  • 页面缓存分配和索引
  • DMA,一系列数据结构的创建

目前的 ULL SDD实现了低于10微妙的IO延迟,然而操作系统内核产生的延迟没有明显变化

本文专注于:

  • Linux内核中的read()write()+fsync()
  • 基于NVMe SSD的Ext4文件系统

For Read Path

研究发现许多剩余的操作不必在设备I/O之前或之后执行

此类操作可以在设备I/O操作进行时执行

因为此类操作大多独立于设备I/O操作,因此考虑让这些操作与IO重叠

For Write Path

缓冲写write(),并不发起IO请求,不能异步处理

由于fsync的回写机制和文件系统崩溃一致性(日志系统),包含部分IO请求

由于文件系统带来的三次IO操作

  1. 数据块写
  2. jbd2发起写入日志Block I/O
  3. 提交Block I/O

这些IO的创建,涉及众多过程(block分配,请求缓冲页,创建和提交bio,设置DMA地址),因此可以让CPU将这些前置操作在IO请求发起前预执行。

For Lightweight Block Layer

传统Block Layer涉及过多过程,推迟了IO指令提交给设备的时间

因为ULL SSD的高速随机IO性能和低速的顺序IO,请求重排的效果很低

简化block layer,针对异步IO stack进行优化

Design

轻量化的Block I/O Layer

LBIO,为LL NVMe SSD而设计,只支持IO submission/completion和IO指令tagging

只使用lbio来表示一个block I/O请求,减少了bio-to-request的时间

每个lbio包括

  • LBA
  • I/O 长度
  • 复制的页面
  • 页面的DMA地址

使用全局的lbio二位数组来记录

行的个数为CPU核心数,行成组被分配到一个NVMe队列

例如8核心,4NVMe队列,每个队列分配2个核心的lbio 当核心数等于队列数时,可以实现无锁的命令提交

lbio在全局数组中的索引用作NVMe指令的tag,减少了之前赋tag的过程

lbio提交后,调用nvme_queue_lbio来提交I/O指令

LBIO不会合并和调度IO请求

Read Path

Ext4文件系统中,由extent status tree保存缓存到物理文件block的映射

预加载映射到内存中,当树太大时,可以只对某个文件预加载

异步页面申请和DMA分配

提前分配空闲页池

为了减少页面DMA的分配,为每个核维护一个DMA映射空闲页(4KB DMA映射页的链表)

当空闲页池不够用时,将退化为同步进行(origin)

缓存页索引

自旋锁防止并发问题,影响效率

在请求发出,但是页面还没有更新时,可能重复请求更新页面

解决方案是不限制request,在request completion阶段解决问题

尽管多个block请求,但是只能有一个页面被索引

对于其他页面,标记为abandoned,中断发生之后,如果标记为abandoned,则清除已经完成的页面

DMA解除映射

原本使用中断来处理,改为当系统空闲或等待一个IO请求时处理

该方式可能会产生漏洞窗口,若不受到恶意访问,不会产生影响,否则用户可以自行选择关闭惰性DMA映射接触

Write && fsync Path

当fsync涉及文件系统中事务时,可以将jbd2日志处理重叠处理

Experiment

基于Linux内核5.0.5版本

使用文件描述符O_AIOS

Evaluation

Conclusion

提出了AIOS

LBIO层

AIOS将I/O路径中的同步操作替换为异步操作,以将与读取和fsync相关的计算与设备I/O访问重叠。

AIOS在Optane SSD上实现了一位数微秒的I/O延迟。

此外,AIOS通过Z-SSD和Optane SSD上的模拟实验和实际测试显著降低延迟和性能改进。

一些启发

  1. 优化I/O可以从CPU的空闲时间分析,需要考虑内核和文件系统的工作流程,最大程度的利用CPU资源,减少空闲。
  2. 硬件设备在发展的同时,软件应该提供必要适配
  3. 减少内核中与I/O相关的结构类型转化,可以有效节省时间开销
  4. 惰性修改会存在安全问题,在保证安全的情况下,可以提高效率
0%