block多队列分析 - 1.概述

1. 前言

本专题文章是对多队列部分学习的笔记。主要以null_dev为例来研究多队列的工作机制, 为了能够凸显多队列的工作流程,只对block层做重点分析说明,对其它代码只做注释性说明。本文是概述部分,说明多队列的基本原理,基本框架和工作流程。

kernel版本:5.10
平台:arm64

注:
为方便阅读,正文标题采用分级结构标识,每一级用一个"-“表示,如:两级为”|- -", 三级为”|- - -“

2. block single queue的问题

在这里插入图片描述
在进入block layer之后,由于对请求队列的访问、查询、完成等处理需要在加锁的情况下进行,因此造成了系统IO性能的瓶颈
在这里插入图片描述
通过上图可以看出由于block层的共享状态导致了系统IO性能的瓶颈

3. block multi-queue的引入

block mq引入的初衷就是要对block层,在各个应用之间、在request的submission和completion之间打破这种共享状态。
在这里插入图片描述
如上图,对每一个cpu core创建一个软队列,并在软队列与硬队列之间在初始化时创建映射关系,这样对于软队列的操作无需加锁。
在这里插入图片描述
应用访问软队列可以做到完全私有访问,submissions基本做到私有访问

4. tag管理

在这里插入图片描述
对于每一个request通过tag来标识,在将request分发给hardware之前会从tag pool中申请,request完成后会将tag归还到tag pool

5. 领域模型

在这里插入图片描述

  • nullb
    nullb为null dev的数据结构,它内嵌blk_mq_tag_set ,一般块设备都会内嵌此数据结构

  • blk_mq_tag_set
    内嵌在块设备结构体nullb中,是多队列的集大成者,是维护多队列各要素的数据结构,包含、tags、tag bitmap、软硬队列映射关系等。它内嵌blk_mq_queue数组map,每个数组成员代表一种类型的硬队列,每种类型的硬队列内部又维护着一个数组mq_map,用于保存软硬队列的映射关系。mq_map数组下标为cpu编号,数组元素为cpu编号所对应的硬队列号。
    每个硬队列一个blk_mq_tags结构体,保存在set->tags[hctx_idx]中, 每个blk_mq_tags是通过sbitmap_queue来描述,每个bit代表一个tag, 对应一个request;

  • blk_mq_queue_map
    为blk_mq_tag_set的内嵌结构体,用于描述软硬队列之间的映射关系。在blk_mq_tag_set中定义了一个blk_mq_queue_map数组,每个数组元素代表一种硬队列类型,主要的硬队列类型包括三种:HCTX_TYPE_DEFAULT,HCTX_TYPE_READ,HCTX_TYPE_POLL
    对于每种硬队列,blk_mq_queue_map中定义了一个mq_map数组,它保存了软队列与硬队列的映射关系,set->map[i]->mq_map数组下标为cpu编号,数组元素为硬队列号

  • blk_mq_tags
    用于tag空间管理。tags中包含了对request及payload的分配, page_list就是用于链接分配出的page; blk_mq_tags与硬队列blk_mq_hw_ctx一一对应,它管理了硬队列的tag bitmap和request,其中每一个tag bit代表了一个request

  • request_queue
    在blk_mq_init_queue_data的过程中会创建request_queue,它通过queue_ctx指向per cpu变量blk_mq_ctx软队列,通过queue_hw_ctx指向硬队列,它的queuedata一般为块设备数据结构nullb; 同时通过backing_dev_info指向了后备设备。
    request_queue可以共享blk_mq_tag_set,通过tag_set_list链接件连入tag_list.
    bio_split是队列的bio池描述符,用来分配bio和bio_vec;
    poll_cb为用于统计的回调函数;
    nr_requests表示软队列的个数;

  • blk_mq_ctx
    软队列,与cpu数目相同,在blk_mq_init_queue_data->blk_mq_init_allocated_queue会分配。它通过hctxs指向对应的硬队列

  • blk_mq_hw_ctx
    硬队列,数目为HCTX_MAX_TYPES, 在blk_mq_init_queue_data->blk_mq_init_allocated_queue->blk_mq_realloc_hw_ctxs时分配。硬队列中包含两种blk_mq_tags,分别为tags(block driver拥有)和sched_tags(io scheduler拥有),可参考blk_mq_hw_ctx中对两者的注释,每个blk_mq_hw_ctx与blk_mq_tags时一一对应的
    在这里插入图片描述
    tags用来保存硬队列本身所具有的blk_mq_tags
    sched_tags用来保存硬队列所对应的调度队列的blk_mq_tags

  • blk_stat_callback
    每个request_queue队列都有一个blk_stat_callback与之对应,会通过定时器回调函数来定时统计request状态

  • elevator_queue
    通用调度队列描述符,每个request_queue,都有一个struct elevator_queue与之对应。其中hash为哈希表,用于快速查找队列中的request。

  • elevator_type
    具体调度队列描述符,如mq-deadline调度器等

参考文档

Solving the Linux storage scalability bottlenecks, Jens Axboe,Vault 2016

  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值