Linux 块设备,Block Layer层架构演变
发布日期:2021-06-30 18:44:50 浏览次数:2 分类:技术文章

本文共 2097 字,大约阅读时间需要 6 分钟。

前言

Block Layer层在整个I/O中负责承上启下,上接文件系统,下接块驱动。

我不想直接讨论代码,希望从一个架构的演变来初探一下Block Layer层。

一、1.0版本

首先我们来了解几个重要的数据结构

1.1 bio

bio代表了一次I/0请求,代表一个块设备的一个扇区或者多个连续扇区的数据请求,扇区是块设备的最小访问单元,bio是文件系统发给Block Layer层的。

1.2 request

request代表块设备可以处理的一次任务单元,一个request由一个bio或者多个扇区相连的bio组成。

1.3 架构图

1.4 小结

Block Layer将文件系统提供的bio变成request,然后交给块设备驱动处理。

二、2.0版本

目前只支持单个进程访问块设备。为了可以支持多进程,我们在块设备驱动中创建一个队列:request_queue,所有的进程发起bio生成的request,会被投递到request_queue,块设备循环处理request_queue中的request。

2.1 request_queue

每一个块设备都有一个工作队列,request_queue,保存准备就绪待处理的request。

2.2 架构图

2.3 小结

这样子就实现了多个进程同时访问块设备,而且在新的一个bio变成request之前,可以先看看该bio能否合并到request_queue的某个request,这样子就可以提升bio处理的效率。

三、3.0版本

好像看起来2.0已经挺完美了,但是request_queue会有一把锁控制,如果多个进程短时间发起多个bio,多个进程不断竞争锁,这样子性能不是很好,我们就引入了plug。

3.1 plug

plug翻译成中文就是塞子,每一个进程会有一个plug,plug是一个request的list,先将一个进程短时间发起的所有bio生成request先堆积到当前进程的plug list,然后在等待特定时机释放plug中的requests到request_queue,这样子可以提升bio处理的效率。

3.2 架构图

3.3 小结

架构越来越完美了,除了上面的流程,在新的一个bio变成request之前,先看看能不能合并到plug里面的某个request中,如果不行在,再看看能否合并到request_queue里面的某个request中,如果不行再变成request,然后放到plug list中,等待积攒一定量之后,统一放置request_queue里面。

四、4.0版本

看起来好像3.0已经很完美了,但是我们会发现3.0有两个明显的优化点。

优化点1:

传统的块设备是机械磁盘,这种硬件是靠一个磁头不断移动进行访问数据的,如果我们可以把所有request排序,这样子就可以提升块设备的访问效率。

举个例子:一个外卖员需要送很多外卖到一个办公楼,他将外卖按楼层排序合并,然后一层层的送,肯定比随机拿一个外卖,然后一层层的送的速度快。

优化点2:

每个块设备单位时间处理request的次数是有限的,如果我们可以提升前台的进程request被处理的优先级,这样子就可以带来更好的用户体验。

4.1 scheduler

翻译成中文就是调度器,scheduler就是可以解决上述的两个优化点,scheduler会在内部创建自定义的各种队列来存放plug释放出来的request,然后scheduler对这个所有的request进行一个调度,按照特定的规则再分发给request_queue,让块设备处理。

4.2 架构图

4.3 小结

有了scheduler,我们就可以实现所有request的重新排序甚至合并,还可以对不同进程的request进行不同的优先级控制,目前linux支持的scheduler有:CFQ,deadline等

5、总结

学习Block Layer层,其实就是学习以上几个重要的部分:bio,request,plug,scheduler,request_queue,而且linux的single-queue架构就是和4.0版的架构差不多,目前手机上基本采用这个single-queue的架构。

linux目前除了支持single-queue,还支持multi-queue,我就不展开讲的,整体的结构很类似。

6、尾巴

整个流程好像看起来很爽,其实我们根本没有关注过进程的调度,我说的进程就是task_struct,多个进程同时发送bio,最后将bio变成request送给了scheduler进行调度,这些代码运行在各自的进程上,然后scheduler再将request分发给块设备处理这个又运行在另一个单独的进程上。如何让多个进程发完request之后休眠,如何让块设备驱动处理完之后唤醒这些休眠的进程。这个唤醒的关键点:在于bio结构体中的bio_end_io_t *bi_end_io这个callback函数指针。

  回复「 篮球的大肚子」进入技术群聊

回复「1024」获取1000G学习资料

转载地址:https://linus.blog.csdn.net/article/details/105259590 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:老罗直播——只要给你一个机会,你就伸双手去接!
下一篇:去华为吗?

发表评论

最新留言

第一次来,支持一个
[***.219.124.196]2024年04月28日 19时42分17秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章

【NLP学习笔记】训练集、验证集和测试集的概念及划分 2019-04-30
【NLP学习笔记】conda换源 2019-04-30
【深度学习笔记】常见的图像增强方法:scaling、rotating、flipping、random cropping 2019-04-30
【深度学习笔记】标准卷积 2019-04-30
【深度学习笔记】组卷积 2019-04-30
【深度学习笔记】循环神经网络和递归神经网络区别 2019-04-30
【学习笔记】英文科技论文常见英语句式积累 2019-04-30
【深度学习笔记】PixelShuffle 2019-04-30
【python3学习笔记】斜杠和双斜杠运算符的区别 2019-04-30
【深度学习笔记】torch.nn.Sequential(* args) 与 torch.nn.Module 2019-04-30
【深度学习笔记】用torch.nn.Sequential()搭建神经网络模型 2019-04-30
【深度学习笔记】用torch.nn.ModuleList搭建神经网络 2019-04-30
【解决错误】AttributeError: module ‘scipy.misc‘ has no attribute ‘imread‘ 2019-04-30
【解决错误】复现RCAN的时候遇到了ImportError: cannot import name ‘_update_worker_pids’ from ‘torch._C’ 2019-04-30
【解决错误】ModuleNotFoundError: No module named ‘skimage‘ 2019-04-30
【深度学习笔记】pytorch的点乘(dot product) 2019-04-30
【深度学习笔记】残差 2019-04-30
【错误解决】cv2.error: OpenCV(4.2.0) C:\projects\opencv-python\opencv\modules\imgproc\sr 2019-04-30
【python学习笔记】读取指定文件夹中的图片,结合边缘保留滤波EPF 2019-04-30
【工具和环境】Linux下安装pycharm 2019-04-30