BLOCK层代码分析(8)IO下发之plug/unplug机制

本文详细介绍了Linux内核中的BLOCK层PLUG/UNPLUG机制,该机制用于提升磁盘处理性能。通过blk_start_plug()开启PLUG,将IO请求加入请求池,当达到一定数量或大小时,通过UNPLUG过程统一调度下发。UNPLUG时机包括:IO数量达到阈值、主动冲刷和调度前检查。blk_plug_flush_list()负责排序并下发IO请求,异步或同步执行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        前面bio bounce过程,bio的切分和合并,request的获取是为IO请求下发做准备工作。当这些准备工作完成后,才进入到真正的IO下发过程。之前在前面章节中介绍过,IO下发基本上有三条路径:经过plug->mq_list往调度器或ctx->rq_lists下发、不经过plug->mq_list往调度器或ctx->rq_lists下发、直接往驱动下发。是否经过plug->mq_list即为是否支持PLUG/UNPLUG机制。本节介绍plug/unplug机制。

        BLOCK层的plug/unplug机制为提升处理磁盘的性能:在开启机制后,IO请求会放置到请求池中(plug过程),当达到某个条件时会将IO请求统一下发(unplug过程)。这样有利于BLOCK请求的合并和排序操作。

1. PLUG的时机

        BLOCK PLUG的开启是由函数blk_start_plug()开启的。对于每个线程描述符task_struct,存在成员blk_plug,若为空表示没有使能PLUG,否则表示已使能PLUG。函数blk_start_plug()进行成员初始化,同时给task_struct->plug赋值。

        在开启BLOCK PLUG后,可以将通过函数blk_add_rq_to_plug()将IO请求加入到plug->mq_list中,且判断所包含的IO请求是否来自多个队列(通过成员multiple_queues)。

2. UNPLUG的时机

        目前UNPLUG的时机有三种:

  1. 所积攒的IO数目达到BLK_MAX_REQUEST_COUNT(16)或遇到的IO大小超过BLK_PLUG_FLUSH_SIZE (128K)时;
  2. 使用blk_finish_plug()主动冲刷;
  3. 在线程被调度前会执行函数sched_submit_work()检查线程plug->mq_list上是否存在IO请求,若存在进行异步冲刷;

        无论主动冲刷还是被动冲刷,最终调用函数blk_plug_flush_list()完成IO请求的下发。首先它会根据IO请求是否来自多个请求队列,若是会依次根据IO请求的mq_ctx(软件队列)/mq_hctx(硬件队列)/扇区位置做排序。待排序后依次将属于相同hctx且相同ctx的IO统一下发异步下发,下发具体函数为blk_mq_sched_insert_requests()(后面章节做介绍)。

        对于blk_plug_flush_list(),在调度前冲刷时会其异步线程(workqueue)做IO下发。其他情况目前都是同步做IO下发。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值