美文网首页
Linux回写存储设备cache机制-FUA,FLUSH

Linux回写存储设备cache机制-FUA,FLUSH

作者: 1哥 | 来源:发表于2022-08-27 15:42 被阅读0次

    1 背景

    很多存储设备,特别是消费级市场,都自带板载cache. 意思是在data 实际写入非易失性的存储介质前就存储设备就发送 IO completion 信号给OS。这样的好处是能更快的响应host 的 IO,但为了确保数据落盘,就需要OS 发送额外的命令(如fsync, sync 或umount ) 以确保数据的完整。此外,系统有多个request 保序的需求。
    Linux block layer 提供了两种机制让filesystem 控制存储设备的cache行为: (Force cache flush)Flush , FUA(Force unit access) Flag。

    2 原理

    2.1 Explicit cache flushes(FLUSH)

    REQ_PREFLUSH:文件系统可以将该flag 和 r/w flag 要一起放入bio, 可确保在已有的write cache 刷入非易失性存储介质后才开始当前的IO 。此外,REQ_PREFLUSH flag 可以用于一个empty 的bio, 用于flush 已有的cache. 推荐blkdev_issue_flush() 用于纯cache flush.

    2.2 Forced Unit Access(FUA)

    REQ_FUA:文件系统可以将该flag 和 r/w flag 要一起放入bio, 可确保在数据写入非易失性存储介质后,才发送IO completion 信号。

    2.3 Linux 中REQ_{PREFLUSH | FUA}

    根据请求的属性和硬件的能力,REQ_{PREFLUSH | FUA} request 分解成由三个可选的步骤:PREFLUSH, DATA,和 POSTFLUSH
    i. 若 request没有数据,只需要REQ_PREFLUSH 才起作用,表示只是一个flush request.
    ii. 如果有数据,REQ_PREFLUSH 表示device cache 必须在data 处理前FLUSH 进device. REQ_FUA 表示一旦request 完成,数据必须写入Non-Volatile 介质中。
    iii. 若device 没有writecache, PREFLUSH 和FUA 没什么区别。请求要么立即完成,要么
    vi. 若device 有writecache, 并支持FUA,REQ_PREFLUSH 转化成PREFLUSH,REQ_FUA 直接和数据一起传给device.
    v. 若device 有writecache, 但不支持FUA,REQ_PREFLUSH 转化成PREFLUSH, REQ_FUA 则转换成POSTFLUSH。

    static unsigned int blk_flush_policy(unsigned long fflags, struct request *rq)
    {
        unsigned int policy = 0;
    
        if (blk_rq_sectors(rq))
            policy |= REQ_FSEQ_DATA;
    
        if (fflags & (1UL << QUEUE_FLAG_WC)) {
            if (rq->cmd_flags & REQ_PREFLUSH)
                policy |= REQ_FSEQ_PREFLUSH;
            if (!(fflags & (1UL << QUEUE_FLAG_FUA)) &&
                (rq->cmd_flags & REQ_FUA))
                policy |= REQ_FSEQ_POSTFLUSH;
        }
        return policy;
    }
    

    3 实现

    3.1 文件系统实现

    文件系统可使用REQ_PREFLUSH and REQ_FUA flag , 不需要关心存储设备是否需要显性cache flush 以及 FUA如何实现。 REQ_PREFLUSH 和 REQ_FUA flag 可用在一个单个bio 中。

    3.2 block driver 实现细节

    3.2.1 make_request_fn based block driver 实现细节

    这种driver 能看到REQ_PREFLUSH 和 REQ_FUA flag. 对于不支持write cache的device:
    可以忽略非空的bio 的 REQ_PREFLUSH and REQ_FUA flag了;处理没有数据的REQ_PREFLUSH requests ,可以什么都不做。
    对于支持write cache 的device:driver需要实现这些flag 的支持。

    3.2.2 request_fn based block driver 实现细节

    对于不支持write cache的设备,没有driver 支持,block layer 处理empty REQ_PREFLUSH request,剥离REQ_PREFLUSH 和 REQ_FUA。
    对于支持write cache 的设备,driver 通过”blk_queue_write_cache(sdkp->disk->queue, true, false); “通知block layer 支持flush writecache. block layer 将一个带payload 的REQ_PREFLUSH request 自动转化成:一个empty REQ_OP_FLUSH request ,紧跟着一个write .
    对于支持FUA的devices, driver 通过“blk_queue_write_cache(sdkp->disk->queue, true, true);” 告知block layer . driver 必须在prep_fn/request_fn中处理REQ_FUA. 若不支持FUA flag,block layer 转化FUA flag成一个write request 和 一个empty REQ_OP_FLUSH。

    相关文章

      网友评论

          本文标题:Linux回写存储设备cache机制-FUA,FLUSH

          本文链接:https://www.haomeiwen.com/subject/oxaqnrtx.html