第6章 设备驱动程序(4)

news2024/11/17 16:27:55

目录

6.5 块设备操作

6.5.5 请求结构

6.5.6 BIO

6.5.7 提交请求

6.5.8 I/O调度

6.5.9 ioctl实现


本专栏文章将有70篇左右,欢迎+关注,查看后续文章。

6.5 块设备操作

6.5.5 请求结构

struct         request {         //放在请求队列上,请求完成放到donelist链表上。

        struct request_queue         *q;

        struct list_head                  queuelist;            //用于挂载到请求队列中。

        struct gendisk                    *rq_disk;

        struct hd_struct                 *part;

        sector_t                             sector;                 //请求的起始扇区。

        unsigned long                   nr_sectors;          //请求包含的的扇区数。

        unsigned int                     current_nr_sectors;

        struct bio                         *bio;                         //表示底层的I/O 请求。

        struct bio                         *biotail;                   //一个请求可包含多个bio,指向最后一个bio。

        void                                 *elevator_private;         //IO调度器设置。

        void                                 *elevator_private2;

        unsigned short                         nr_phys_segments;        //请求涉及连续物理区域数。

        unsigned short                         nr_hw_segments;           //重排序的请求中连续物理区域数。

        enum rq_cmd_type_bits         cmd_type;                        //如:REQ_TYPE_FS。

        unsigned int                        cmd_flags;                          //如:_REQ_RW表示数据传输方向。

        unsigned int                        cmd_len;

}

BIO:用于内核和设备间传输数据。下节讲。

struct request在更高层次表示块设备的整体I/O请求,包含多个struct bio

6.5.6 BIO

bio:描述单个IO读写请求。

struct         bio {

        struct bio                         *bi_next;

        struct block_device         *bi_bdev;         // 对应块设备。

        sector_t                           bi_sector;        // 请求传输的开始扇区号。

        unsigned int                    bi_size;           // 请求数据的长度。

        unsigned short               bi_vcnt;           // bi_io_vec数组元素个数,即数据缓冲区数量。

        unsigned short              bi_idx;              // 作为数组bi_io_vec的索引。

        struct bio_vec               *bi_io_vec;

}

struct         bio_vec {

        struct page          *bv_page;         // 缓冲区所在页。

        unsigned int         bv_len;             // 缓冲区长度。

        unsigned int         bv_offset;         // 缓存区在页内的偏移。

};

6.5.7 提交请求

内核将IO请求提交给设备,步骤:

        1. 创建一个bio以描述请求 ,并嵌入到request中,放到request_queue中。

        2. 内核处理请求队列,并执行bio中的请求。

bio创建后,调用struct request_queue中make_request_fn函数指针,将新请求加入请求队列。

而request_fn用于提交请求。

1. 创建IO请求

submit_bio:

        根据bio创建一个新request。

        使用make_request_fn将request加入到request_queue中。

2. 队列插入

为提高IO性能,尽可能重排或合并各个请求。

队列空闲时:处理队列中请求。否则只添加请求到队列,而不处理。

请求插入队列后,后续何时处理请求?

       1. 定时器。
        2. 请求超过阈值。

3. 执行请求

执行请求:

        struct request_queue->request_fn()函数指针。

struct request_queue    *blk_init_queue(request_fn_proc     *rfn,     spinlock_t     *lock)

        用于设置request_fn()函数指针。

        不同设备驱动中调用该函数设为不同函数。

6.5.8 I/O调度

I/O调度器:也叫电梯。

        用于调度和重排磁盘IO读写操作请求。以优化磁盘访问的顺序和效率。

一个调度器包含的操作:

struct elevator_ops {

        elevator_merge_fn                 *elevator_merge_fn;

                //检查新请求是否可以和现有请求合并。

        elevator_merged_fn                 *elevator_merged_fn;

                //合并后调用。

        elevator_merge_req_fn         *elevator_merge_req_fn;

                //执行请求合并。

        elevator_allow_merge_fn         *elevator_allow_merge_fn;

                //是否可以将当前请求与现有请求合并。

        elevator_bio_merged_fn         *elevator_bio_merged_fn;

                //当一个bio被合并到一个请求中时调用。

        elevator_dispatch_fn                 *elevator_dispatch_fn;

                //从指定队列中选择下一个调度的请求给设备驱动。

        elevator_add_req_fn                 *elevator_add_req_fn;

                //向队列添加请求。

        elevator_activate_req_fn                 *elevator_activate_req_fn;

        elevator_deactivate_req_fn             *elevator_deactivate_req_fn;

                //当请求变为活动/非活动时调用。

        elevator_completed_req_fn         *elevator_completed_req_fn;

                //当一个请求完成时调用。

        elevator_init_icq_fn                 *elevator_init_icq_fn;

        elevator_exit_icq_fn                 *elevator_exit_icq_fn;

                //初始化/清理 I/O上下文队列。

        elevator_set_req_fn                 *elevator_set_req_fn;

        elevator_put_req_fn                 *elevator_put_req_fn;

        elevator_may_queue_fn         *elevator_may_queue_fn;

                //是否可将请求添加到请求队列。

        elevator_init_fn                 *elevator_init_fn;

        elevator_exit_fn                 *elevator_exit_fn;

                //调度器初始化时、退出时调用。

}

请求上下文(I/O Context Queue, ICQ):

        ICQ 存储与请求相关上下文,如文件系统元数据、锁状态等。

表示一个调度器:

struct         elevator_type

{

        struct kmem_cache         *icq_cache;

        struct elevator_ops         ops;

        size_t                             icq_size;

        size_t                             icq_align;

        struct elv_fs_entry         *elevator_attrs;         //sysfs中的属性。

        char                                 elevator_name[ELV_NAME_MAX];         //调度器名称。

        struct module                 *elevator_owner;

        struct list_head                 list;         //连接所有IO调度器。

};

内核的IO调度器有:

        1. elevator_noop:

                简单,先来先服务。可合并请求,但不能重排。

                使用场景:

                        1. 可自行重排的智能硬件。

                        2. 不用寻道的设备, 如闪存。

        2. iosched_deadline:

                目的:

                        最小化寻道次数。

                        尽可能在一定时间内完成。

        3. iosched_cfq:

                完全公平队列。默认调度器。

                每个进程有一个队列,轮询调度多个队列。

拓展

常见I/O调度算法:

        完全公平队列(CFQ):

                为每个进程提供公平访问磁盘机会。将磁盘带宽分配给不同进程。

                适用于多任务公平共享磁盘资源环境。

        Deadline:

                适用于低延迟应用,如实时应用,数据库。

        Noop:

                不重排序不优化。

                适用不需要额外调度开销的情况,如SSD设备。

        电梯算法:

                优化了磁盘访问顺序,减少寻道时间。

                模拟电梯上下移动,根据磁头当前位置和移动方向,调度最近请求 。

                对于磁盘访问密集型且随机的I/O,显著提高性能。

                缺点:

                        当磁头频繁改变方向时,一些请求可能长时间等待。

                        因此需要根据实际应用的特点和需求权衡。

6.5.9 ioctl实现

系统调用 - > sys_ioctl -> vfs_ioctl

blkdef_ioctl:实现了某些ioctl,对于所有块设备都可用。

        如:读取设备分区信息,设备总长度。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1839083.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

BFS 1块、算多少次

目录 1.矩阵内部的1块 2.从1开始&#xff0c;1或乘2&#xff0c;计算要多少次达到n 3.迷宫路径 1.矩阵内部的1块 #include <iostream> #include <vector> #include <cmath> #include <string> #include <cstring> #include <queue> usi…

现代谱估计分析信号的功率谱(1)---AR 模型谱估计

本篇文章是博主在通信等领域学习时&#xff0c;用于个人学习、研究或者欣赏使用&#xff0c;并基于博主对通信等领域的一些理解而记录的学习摘录和笔记&#xff0c;若有不当和侵权之处&#xff0c;指出后将会立即改正&#xff0c;还望谅解。文章分类在通信领域笔记&#xff1a;…

1951–2021年欧洲地区木本植物的格网物候数据集

本数据集包含1951–2021年欧洲地区&#xff08;3457′N – 723′N&#xff0c;253′W – 403′E&#xff09;6种木本植物的逐年展叶始期和开花始期格网数据&#xff0c;空间分辨率为0.1&#xff0c;时间分辨率为1天。数据集的质量评估表明&#xff0c;欧洲地区各物种展叶始期和…

车载语音识别系统语音数据采集标注案例

随着人工智能技术的不断发展&#xff0c;其在我们日常生活工作场景中的应用也越来越普及&#xff0c;人工智能技术在不同场景的普及大大的提高了我们日常生活、工作的高效性和便利性。以我们的日常出行为例&#xff0c;车载语音识别系统便是一种典型的人工智能应用场景。 车载…

大咖专栏 | AI 时代下,我们可以拥有怎样的数据库?

Hi&#xff0c;各位朋友们&#xff0c;我是 KaiwuDB 高级架构师赵衎衎。 KaiwuDB 始于万物互联时代下千万条数据洪流中&#xff0c;我们持续打磨构造了更加灵活兼容的分布式多模架构&#xff0c;实现了海量异构数据高性能、低成本的集中管理… …这些底层特性都在为后续提供更…

初见DP

线性DP 例题1 1143. 最长公共子序列 &#xff08;LCS&#xff09; 子序列不连续 给定两个字符串 text1 和 text2&#xff0c;返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 &#xff0c;返回 0 。 一个字符串的 子序列 是指这样一个新的字符串&#x…

单片机第五季-第八课:STM32CubeMx和FreeRTOS

1&#xff0c;FreeRTOS背景介绍 RTOS简介&#xff1a; 实时操作系统&#xff0c;本用于追求实时性的嵌入式系统&#xff0c;典型&#xff1a;ucos/uclinux/vxworks&#xff1b; 特点&#xff1a;中断响应快、一般可嵌套中断、使用实地址、多任务&#xff1b; &#xff08;实…

如何用Vue3构建一个交互式树状图

本文由ScriptEcho平台提供技术支持 项目地址&#xff1a;传送门 Vue 3 ApexCharts Treemap 组件&#xff1a;可视化多维数据 应用场景 树形图&#xff08;Treemap&#xff09;是一种可视化多维数据的有效方式&#xff0c;特别适用于展示层次结构数据或按类别分组的数据。它…

Flink 资源静态调度

本内容是根据 Flink 1.18.0-Scala_2.12 版本源码梳理而来。本文主要讲述任务提交时&#xff0c;为 Task 分配资源的过程。 以下是具体步骤讲解&#xff1a; TaskManager 资源注册 TaskManager 再启动时&#xff0c;会向 ResourceManager 注册资源。ResourceManager 会将 Tas…

Debian12安装Nvidia官方驱动

1、下载驱动&#xff08;下载到一个英文目录例如你的用户目录/home/用户名下&#xff0c;我下载到dowload目录&#xff0c;由于默认显示中文&#xff0c;在命令行不支持中文显示的是一串数字&#xff0c;当然你仍然可以cd 那串数字进目录&#xff0c;显示有有引号就加引号&…

香港优才计划申请打分、材料、递交攻略,2024年获批后我来分享

香港优才计划这两年很多人弄啊&#xff0c;糖爸作为获批过来人&#xff0c;我来给大家分享香港优才计划申请攻略。 一、香港优才计划如何计算分数&#xff1f; 香港优才计划申请条件分2部分&#xff1a;第一是基本资格要求&#xff0c;第二是计分制度&#xff1b; 基本条件简…

前端框架中的路由(Routing)和前端导航(Front-End Navigation)

聚沙成塔每天进步一点点 本文回顾 ⭐ 专栏简介前端框架中的路由&#xff08;Routing&#xff09;和前端导航&#xff08;Front-End Navigation&#xff09;1. 路由&#xff08;Routing&#xff09;1.1 定义1.2 路由的核心概念1.2.1 路由表&#xff08;Route Table&#xff09;1…

Pentest Muse:一款专为网络安全人员设计的AI助手

关于Pentest Muse Pentest Muse是一款专为网络安全研究人员和渗透测试人员设计和开发的人工智能AI助手&#xff0c;该工具可以帮助渗透测试人员进行头脑风暴、编写Payload、分析代码或执行网络侦查任务。除此之外&#xff0c;Pentest Muse甚至还能够执行命令行代码并以迭代方式…

【信息资源组织与管理】【开卷考】如何准备 期末考试复习必备

索引篇 先去xhs找了开卷考有什么准备技巧&#xff0c;来自Prozac ❗️首先&#xff0c;适用于考试范围为课本内容或者课堂内容&#xff0c;如果有那种拓展题&#xff0c;脱离课本的&#xff0c;那我就没办法了。 ✅一定要熟悉熟悉熟悉课本 1. 第一遍略看课本&#xff0c;可以不…

navcat 随机生成数据

我最近才知道navcat能随机生成数据&#xff0c;所以分享下 下一步&#xff0c;下一步就可以了&#xff0c;我们就成功了

芯片验证分享9 —— 芯片调试

大家好&#xff0c;我是谷公子&#xff0c;之前的课程给大家讲了验证原则、激励设计和代码审查&#xff0c;今天我们来讲芯片调试。 芯片调试是执行一次成功的验证之后要进行的工作。记住&#xff0c;所谓成功的验证&#xff0c;是指它可以证明芯片没有实现预期的功能。调试主…

不是所有洗碗机都能空气除菌 友嘉灵晶空气除菌洗碗机评测

精致的三餐让你以为生活是“享受”&#xff0c;可饭后那些油腻的锅碗瓢盆却成了你我美好生活的最大障碍。想要只吃美食不洗碗&#xff0c;那一台优秀的洗碗机就必不可少了&#xff01;今天&#xff0c;ZOL中关村在线要评测的就是这样一台不光洗得干净更能有效除菌抑菌的洗碗机—…

UE4_材质_湿度着色器及Desaturation算法_ben材质教程

学习笔记&#xff0c;不喜勿喷&#xff01;侵权立删&#xff0c;祝愿美好生活越来越好。 效果图&#xff1a; 原图&#xff1a; 1、使用初学者内容包的材质 我们这里使用虚幻自带的材质M_Brick_Clay_Old,复制一个更名为M_Brickclayoldwet材质。 2、添加去饱和度Desaturation节…

【尝鲜】SpringCloudAlibaba AI 配置使用教程

1、环境配置 maven依赖pom.xml 注意配置远程仓库&#xff0c;原因见&#xff1a;Unresolved dependency: ‘org.springframework.ai:spring-ai-core:jar:0.8.1’ <dependencies><!--Base--><dependency><groupId>org.springframework.boot</group…

【Spine学习14】之 裁剪

1、新建裁剪 2、在页面中随便点几下 圈出对应位置 3、点编辑裁剪 或者按空格键 退出编辑模式&#xff0c; 页面就只剩下对应区域&#xff0c;这个区域可以任意拖动 放大缩小显示。 tips&#xff1a; 如果手动选择区域描绘不准确&#xff0c;可以启用对应图片的网格 然后复制…