LWN:让UFS存储设备支持turbo-write mode
Supporting the UFS turbo-write mode
By Jake Edge
May 20, 2019
LSFMM
UFS是Universal Flash Storage的简称,跟eMMC设备类似的存储设备。Avri Altman在 2019 LSFMM Summit上介绍了一下怎样支持UFS的turbo-write mode(倍速写入模式)。
NAND flash设备里面,每个存储单元可以存储3个bit的信息(triple-level cell,TLC),不过这样就会比只存一个bit的cell(single-level cell, SLC)要慢。TLC通常来说要比SLC慢2到3倍。最新版本的UFS specification(技术规范)很可能会加上一个turbo-write模式,它主要是利用一个SLC buffer来快速满足写入,然后后续找时间搬到慢速的TLC存储单元里去。Altman想跟大家讨论turbo-write mode有什么应用场景。
Ted Ts’o想知道谁来管理这些block(存储块)?是需要Linux来把数据从SLC搬到TLC吗?Altman的回答是操作系统并不知道这个信息,而是设备自己会来管理物理地址更改以及复制搬移的工作。Ts’o想知道如果所有的write操作都设成turbo模式,会不会导致存储设备的寿命大大减小(因为一次写入会引出后续的多次copy操作)。Altman同意他的卡饭,如果每个write request都经过SLC的话,flash存储设备肯定很快损坏。
Damien Le Moal认为开发者需要了解这个device内部的wear-leveling(块寿命平衡算法),才能知道如何更好的利用turbo-mode。而且随着设备的使用时间加长,某一天开始,这个设备应该会彻底忽略所有turbo-write操作,因为也许SLC已经满了,或者wear-leveling算法限制住了。如果没有更多信息让操作系统知道,那么操作系统就不可能采取正确的行为。这些管理操作就应该放到UFS存储设备的Linux驱动程序里。
不过Ts’o觉得不合适,因为device没有给开发者什么可以操控的点。例如复制数据到TLC会花多长时间,kernel根本不知道,会不会影响同一时间进行的read/write操作的性能?太多未知数了。很可能不同的设备还会有不同的SLC vs TLC比例,这些都会影响我们的策略。
Altman觉得操作系统可以有API查询到设备里有多少SLC空间,不过如果能有个方案不依赖这类信息的话,那就更好了。Le Moal还是认为甚至需要跟多的信息才能定下来policy,尤其是wear-leveling的信息。不过James Bottomley认为对application来说,wear-leveling是它们不需要关心的信息。application才不会因为别的进程在做写操作导致wear-leveling拖慢设备而做什么特殊处理。Ts’o觉得最简单的做法就是把kernel里的所有同步性的写操作(synchronous write)都配成turbo write,其他的后台写操作都使用普通write模式,不过这样做了之后,可能设备也只能支撑3个月的使用周期。。。
Le Moal坚持认为应该在驱动程序里决定是否用turbo-write,因为驱动程序能看到所有的读写操作,根据这些信息它应该能做出决定。不过Ewan Milne认为这些决策应该留给更底层:让设备自己的firmware来决定。SLC/TLC组合的这种方式能够让大容量设备有更好的performance表现。而设备本身最了解自己的当前情况,kernel这边又能做什么来做的更好吗?不过Ts’o紧接着指出设备firmware本身不知道还有其他进程可能在等着write完成,而kernel就可以区分出synchronous write和低优先级的写操作。
Bottomley问,如果设备里的SLC部分损坏了,会出现什么情况?会导致整个设备都损坏不可用了,还是只是降速使用?Altman说知会降低性能(degrade)而已。Bottomley认为这样的话那么就干脆让kernel所有的写操作都使用turbo mode,这样起初几个月都是性能很好,过几个月变慢一些。Ts’o说这些设备通常都是给mobile device(移动设备,例如手机)的,如果3个月之后变慢了,厂商根本不担心,因为手机评测专家们才不会测试3个月那么久。
最后,Le Moal认为kernel这边可以把要求turbo-write这个信息作为hint传递给设备,但是设备可以自己去决定是否真的使用turbo-write。就像I/O priority一样。不过Martin Petersen跳出来强烈反对,他认为那些关于I/O priority的hint现在看起来完全没有达到目的。如果告诉存储设备这些数据是metadata或者文件系统日志,可能还有点价值,而告诉设备这个读写操作的I/O priority,基本没有什么用处。
Chris Mason从实用角度出发,认为这里的真正问题是没有一个客观评判标准。首先应该把这些主意综合起来,定义出一个评判标准,然后再拿各个方案出来对比。
Ts’o觉得这个情况还算是好的,要比通用的SCSI设备好解决。因为UFS只会用于mobile device。Chrisoph Hellwig不赞成这种说法,现在已经有一些其他设备在考虑使用UFS了,他也觉得laptop这类场景应该不会考虑UFS。Ts’o说,总之UFS设备不可能用来支撑Oracle企业级数据库这种类型的应用,因此只要针对mobile类型的workload来微调设备行为即可。
不过,Ts’o也认为kernel开发者通常不喜欢按照某个特殊场景来针对性的实现解决方案。手持设备的厂商,通常都很关注benchmark,不太考虑设备的健康状况和还能用多久(endurance)。Bottomley认为,上层软件可以给出各种hint传递到驱动程序,驱动或者设备上的firmware可以决定怎么用。最终Altman得到的结论是,还是要在UFS的设备驱动程序层来集中做出这些决策。
Bottomley建议这个驱动程序要检查synchronous bit,对这些write操作就配成turbo mode,然后用benchmark来看效果如何。Ts’o提示ext4日志文件的写入也是synchronous的,刚好能用上。比较麻烦的是如何测出benchmark,因为各种场景下SLC上数据搬移的行为是怎样的,需要有个方法能测量出来。Bottomley认为就用现有的hint即可,后续有需要再加新的,只要有数据证明有用,就可以加到kernel里。
Altman还想讨论一些具体策略,SLC buffer的内容应该在什么时候搬到TLC。Ts’o认为应该在设备有外接电源的时候,更加频繁的做这个数据搬移,或者在这个存储设备很空闲的时候也行。不过还需要根据SLC buffer占用比例,反正驱动程序或者设备firmware应该知道这个信息。所以关于turbo-write,计划先做出一个原型实现,然后根据需要,再在kernel里面增加相关支持。
最后,Altman说,turbo-write什么时候进行,以及SLC内容的排空,这两方面的策略都需要UFS driver来处理。Ts’o赞同,因为他看到mobile-storage community(移动设备存储相关领域负责者)通常都不爱在设备里使用更智能的策略。
if that were not the case, one could imagine other engineering solutions, such as well-defined flush policies that the kernel could choose from.(译者注:我没看懂 -_-!)