当前位置: 首页 > news >正文

blk_mq_init_queue函数学习记录

blk-mq编程,主要要调用两个函数进行初始化工作,blk_mq_init_queue这是第二个。该函数先是申请了struct request_queue结构,这个请求队列后面用于赋值给磁盘那个结构体的相应成员。

struct request_queue *blk_mq_init_queue(struct blk_mq_tag_set *set)
{struct request_queue *uninit_q, *q;//分配struct request_queue并初始化uninit_q = blk_alloc_queue_node(GFP_KERNEL, set->numa_node, NULL);if (!uninit_q)return ERR_PTR(-ENOMEM);/*1:分配每个cpu专属的软件队列并初始化2:分配硬件队列,并初始化3:建立软件队列和硬件队列的联系*/q = blk_mq_init_allocated_queue(set, uninit_q);if (IS_ERR(q))blk_cleanup_queue(uninit_q);return q;
}
EXPORT_SYMBOL(blk_mq_init_queue);

blk_mq_init_allocated_queue函数分析

一眼望过去,确实有点复杂,不过,多看几遍就好了,
这里面,主要就是给struct request_queue *q结构体里面的成员变量赋值的,简单的变量赋值就不分析了,看看它调用的函数进行分析。

struct request_queue *blk_mq_init_allocated_queue(struct blk_mq_tag_set *set, struct request_queue *q)
{/* mark the queue as mq asap */q->mq_ops = set->ops;q->poll_cb = blk_stat_alloc_callback(blk_mq_poll_stats_fn, blk_mq_poll_stats_bkt, BLK_MQ_POLL_STATS_BKTS, q);if (!q->poll_cb)goto err_exit;q->queue_ctx = alloc_percpu(struct blk_mq_ctx);//percpu变量 软件队列if (!q->queue_ctx)goto err_exit;/* init q->mq_kobj and sw queues' kobjects */blk_mq_sysfs_init(q); //主要是初始化kobject变量//二级指针 硬件队列q->queue_hw_ctx = kcalloc_node(nr_cpu_ids, sizeof(*(q->queue_hw_ctx)), GFP_KERNEL, set->numa_node);if (!q->queue_hw_ctx)goto err_percpu;//赋值q->mq_map,这个数组保存了每个CPU对应的硬件队列编号q->mq_map = set->mq_map;blk_mq_realloc_hw_ctxs(set, q);if (!q->nr_hw_queues)goto err_hctxs;/*定时器初始化,设置超时时间*/INIT_WORK(&q->timeout_work, blk_mq_timeout_work);blk_queue_rq_timeout(q, set->timeout ? set->timeout : 30 * HZ);q->nr_queues = nr_cpu_ids;q->queue_flags |= QUEUE_FLAG_MQ_DEFAULT;if (!(set->flags & BLK_MQ_F_SG_MERGE))queue_flag_set_unlocked(QUEUE_FLAG_NO_SG_MERGE, q);q->sg_reserved_size = INT_MAX;INIT_DELAYED_WORK(&q->requeue_work, blk_mq_requeue_work);INIT_LIST_HEAD(&q->requeue_list);spin_lock_init(&q->requeue_lock);blk_queue_make_request(q, blk_mq_make_request);if (q->mq_ops->poll)q->poll_fn = blk_mq_poll;/** Do this after blk_queue_make_request() overrides it...*/q->nr_requests = set->queue_depth; //防止被覆盖/** Default to classic polling*/q->poll_nsec = -1;if (set->ops->complete)blk_queue_softirq_done(q, set->ops->complete);blk_mq_init_cpu_queues(q, set->nr_hw_queues);blk_mq_add_queue_tag_set(set, q);blk_mq_map_swqueue(q);if (!(set->flags & BLK_MQ_F_NO_SCHED)) {int ret;ret = elevator_init_mq(q);if (ret)return ERR_PTR(ret);}return q;
err_hctxs:kfree(q->queue_hw_ctx);
err_percpu:free_percpu(q->queue_ctx);
err_exit:q->mq_ops = NULL;return ERR_PTR(-ENOMEM);
}
EXPORT_SYMBOL(blk_mq_init_allocated_queue);

blk_stat_alloc_callback

这个函数一看也没什么分析的,主要也是给poll_cb进行赋值,采用了很多的默认函数进行赋值。

struct blk_stat_callback *
blk_stat_alloc_callback(void (*timer_fn)(struct blk_stat_callback *),int (*bucket_fn)(const struct request *), unsigned int buckets, void *data)
{struct blk_stat_callback *cb;cb = kmalloc(sizeof(*cb), GFP_KERNEL);if (!cb)return NULL;cb->stat = kmalloc_array(buckets, sizeof(struct blk_rq_stat), GFP_KERNEL);if (!cb->stat) {kfree(cb);return NULL;}cb->cpu_stat = __alloc_percpu(buckets * sizeof(struct blk_rq_stat), __alignof__(struct blk_rq_stat));if (!cb->cpu_stat) {kfree(cb->stat);kfree(cb);return NULL;}cb->timer_fn = timer_fn;cb->bucket_fn = bucket_fn;cb->data = data;cb->buckets = buckets;timer_setup(&cb->timer, blk_stat_timer_fn, 0);return cb;
}
EXPORT_SYMBOL_GPL(blk_stat_alloc_callback);

blk_mq_sysfs_init

接着到这个函数,也是变量的初始化工作,struct request_queue队列里面的kobject变量初始化,以及取出在每一个cpu上q->queue_ctx结构体,然后对齐成员kobject变量进行初始化。

void blk_mq_sysfs_init(struct request_queue *q)
{struct blk_mq_ctx *ctx;int cpu;kobject_init(&q->mq_kobj, &blk_mq_ktype);for_each_possible_cpu(cpu) {ctx = per_cpu_ptr(q->queue_ctx, cpu);//返回每个cpu上的q->queue_ctx变量的首地址kobject_init(&ctx->kobj, &blk_mq_ctx_ktype);}
}

blk_mq_realloc_hw_ctxs

这个函数相对来说比较重要。后面再补充。

在这里插入代码片

blk_queue_make_request

这个函数也是给q的其成员赋值的,先大概熟悉一下,如果有实际的调试分析,需要了解某个参数的值,到时再回来看吧。

void blk_queue_make_request(struct request_queue *q, make_request_fn *mfn)
{/** set defaults*/q->nr_requests = BLKDEV_MAX_RQ; //这个值后面会重新赋值进行覆盖q->make_request_fn = mfn;blk_queue_dma_alignment(q, 511);blk_queue_congestion_threshold(q);q->nr_batching = BLK_BATCH_REQ;blk_set_default_limits(&q->limits);
}
EXPORT_SYMBOL(blk_queue_make_request);

blk_queue_softirq_done

也是赋值,IO操作完成时,会调用这个回调函数。

void blk_queue_softirq_done(struct request_queue *q, softirq_done_fn *fn)
{q->softirq_done_fn = fn;
}
EXPORT_SYMBOL(blk_queue_softirq_done);

blk_mq_init_cpu_queues

static void blk_mq_init_cpu_queues(struct request_queue *q, unsigned int nr_hw_queues)
{unsigned int i;for_each_possible_cpu(i) { //硬件队列数/*返回这个变量在编号为i的cpu上的起始地址*/struct blk_mq_ctx *__ctx = per_cpu_ptr(q->queue_ctx, i);struct blk_mq_hw_ctx *hctx;//其成员做一些赋值操作__ctx->cpu = i;spin_lock_init(&__ctx->lock);INIT_LIST_HEAD(&__ctx->rq_list);__ctx->queue = q;/** Set local node, IFF we have more than one hw queue. If* not, we remain on the home node of the device*/hctx = blk_mq_map_queue(q, i); //取出每个cpu上的硬件队列if (nr_hw_queues > 1 && hctx->numa_node == NUMA_NO_NODE)hctx->numa_node = local_memory_node(cpu_to_node(i));}
}

blk_mq_add_queue_tag_set


blk_mq_map_swqueue


相关文章:

blk_mq_init_queue函数学习记录

blk-mq编程,主要要调用两个函数进行初始化工作,blk_mq_init_queue这是第二个。该函数先是申请了struct request_queue结构,这个请求队列后面用于赋值给磁盘那个结构体的相应成员。 struct request_queue *blk_mq_init_queue(struct blk_mq_t…...

高防服务器的工作原理

在当今互联网时代,网络安全问题日益突出,各种网络攻击层出不穷。为了保护企业的网络安全,高防服务器应运而生。那么,你是否了解高防服务器的工作原理呢?下面就让我们一起来探索一下。 高防服务器是一种能够有效抵御各种…...

2023.11.19使用flask制作一个文件夹生成器

2023.11.19使用flask制作一个文件夹生成器 实现功能: (1)在指定路径上建立文件夹 (2)返回文件夹的路径和建立成功与否的提示 main.py import os from flask import Flask, request, jsonify, render_templateapp F…...

【04】ES6:字符串的扩展

一、模板字符串 模板字符串是可以插入表达式的字符串字面量。模板字符串和传统字符串比较,存在以下特点: 1、使用反单引号 传统字符串字面量使用单引号 ‘’ 或者双引号 “”,模板字符串使用反单引号(backquote) …...

Docker可视化管理界面工具Portainer安装

Portainer是Docker容器管理界面工具,可以直观的管理Docker。 部署也很简单: 官方安装文档地址 1、创建数据卷 docker volume create portainer_data2、下载允许容器 docker run -d -p 8000:8000 -p 9443:9443 --name portainer --restartalways -v /v…...

css实现水波纹效果

css实现水波纹效果 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title><styl…...

一种全新且灵活的 Prompt 对齐优化技术

并非所有人都熟知如何与 LLM 进行高效交流。 一种方案是&#xff0c;人向模型对齐。 于是有了 「Prompt工程师」这一岗位&#xff0c;专门撰写适配 LLM 的 Prompt&#xff0c;从而让模型能够更好地生成内容。 而另一种更为有效的方案则是&#xff0c;让模型向人对齐。 这也是…...

8:kotlin 类型检查和转换(Type checks and casts)

在运行时可以执行类型检查以检查对象的类型。类型转换将对象强制转换为不同的类型 is 和 !is 可以使用is或者!is来判断实例是不是指定的类型 fun main() {var obj : Any "cast"if (obj is String) {println(obj.length) // 4}obj 123if (obj !is String) { pr…...

命令模式 (Command Pattern)

定义 命令模式&#xff08;Command Pattern&#xff09;是一种行为型设计模式&#xff0c;它将一个请求封装为一个对象&#xff0c;从而允许用户使用不同的请求、队列或日志来参数化其他对象。命令模式也支持可撤销的操作。主要目的是将命令的发送者和接收者解耦&#xff0c;引…...

蓝桥杯官网练习题(奇怪的数列)

题目描述 从 X 星截获一份电码&#xff0c;是一些数字&#xff0c;如下&#xff1a; 13 1113 3113132113 1113122113 ⋯ YY 博士经彻夜研究&#xff0c;发现了规律&#xff1a; 第一行的数字随便是什么&#xff0c;以后每一行都是对上一行"读出来" 比如第 2…...

flink的异常concurrent.TimeoutException: Heartbeat of TaskManager with id的解决

背景 在使用flink进行集成测试时&#xff0c;我们会使用MiniClusterWithClientResource类&#xff0c;但是当我们断点导致在某个方法执行的时间比较长时&#xff0c;会有错误发生&#xff0c;那么该如何解决这个错误呢&#xff1f; 处理concurrent.TimeoutException: Heartbe…...

火电安全事故vr模拟仿真培训强交互更真实

VR消防&#xff0c;利用VR虚拟现实技术&#xff0c;将VR和消防教育融合在一起达到寓教于乐的效果&#xff0c; VR消防教育是对于家中、校园内、大型商场、公司办公室等情景产品研发的消防安全培训类VR系统软件&#xff0c;根据互动体验、互动、视角实际操作、视听觉系统多度自然…...

ELK企业级日志分析平台

目录 一、elasticsearch 1、集群部署 2、cerebro部署 3、elasticsearch-head插件部署 4、elasticsearch集群角色分类 二、logstash 1、部署 2、elasticsearch输出插件 3、file输入插件 4、file输出插件 5、syslog 插件 6、多行过滤插件 7、grok过滤 三、kibana数…...

.NET面试题1

1.什么是C#&#xff1f; C#&#xff08;读作"C sharp"&#xff09;是一种通用的、面向对象的编程语言&#xff0c;由Microsoft开发。它是一种静态类型语言&#xff0c;支持强类型检查和面向对象编程&#xff08;OOP&#xff09;的概念。C#主要用于开发Windows应用程序…...

mongodb 日志详情

1 mongodb日志简介 MongoDB的日志包括两个主要部分&#xff1a;操作日志&#xff08;oplog&#xff09;和系统日志。 1.1 操作日志 操作日志&#xff08;oplog&#xff09;是一个特殊的集合&#xff0c;用于记录所有对数据库进行的操作&#xff08;如插入、更新和删除&#x…...

Oracle中文显示???????解决办法

项目场景&#xff1a; Oracleoracle中文显示???解决办法 问题描述 原因分析&#xff1a; Oracle中文显示???通常是由于字符集不匹配或者编码问题导致的。当数据库中的数据使用的是某种字符集&#xff0c;而客户端或者应用程序使用的是另一种字符集时&#xff0c;就会出…...

Java查询数据放入word模板中并在前端导出下载

需求&#xff1a;查询数据放入word模板中并在前端导出下载 解决方法&#xff1a;在模板的位置定义参数如 {{name}} {{age}}等等&#xff0c;使用 poi 处理 伪代码&#xff1a; PostMapping("/practiceAppr")public AjaxResult practiceAppr(OutputStream outputSt…...

HarmonyOS ArkTS 应用添加弹窗(八)

概述 在我们日常使用应用的时候&#xff0c;可能会进行一些敏感的操作&#xff0c;比如删除联系人&#xff0c;这时候我们给应用添加弹窗来提示用户是否需要执行该操作&#xff0c;如下图所示&#xff1a; 弹窗是一种模态窗口&#xff0c;通常用来展示用户当前需要的或用户必须…...

排序算法-----快速排序(非递归实现)

目录 前言 快速排序 基本思路 非递归代码实现 算法分析 空间复杂度 时间复杂度 稳定性 前言 很久没跟新数据结构与算法这一栏了&#xff0c;因为数据结构与算法基本上都发布完了&#xff0c;哈哈&#xff0c;那今天我就把前面排序算法那一块的快速排序完善一下&#xff0…...

el-input限制输入整数等分析

文章目录 前言1、在 Vue 中&#xff0c;可以使用以下几种方式来限制 el-input 只能输入整数1.1 设置input 的 type为number1.2 使用inputmode1.3 使用自定义指令1.4 使用计算属性1.5 使用 onafterpaste ,onkeyup1.6 el-input-number 的precision属性 总结 前言 input 限制输入…...

保姆级教程:在AutoSar CP架构下为CAN报文配置SecOC(基于Davinci Configurator)

实战指南&#xff1a;基于Davinci Configurator的AutoSar CP架构SecOC配置全解析 在汽车电子领域&#xff0c;信息安全已成为功能安全之外的另一大核心诉求。随着车载网络攻击面不断扩大&#xff0c;传统CAN总线"裸奔"式的通信方式正面临严峻挑战。作为AutoSar标准中…...

Dev Containers 远程开发环境优化实战:9大性能瓶颈诊断清单与3分钟修复法

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;Dev Containers 远程开发环境优化面试概览 Dev Containers&#xff08;开发容器&#xff09;正成为现代云原生开发与远程协作的关键基础设施。在技术面试中&#xff0c;候选人常被考察对容器化开发环境…...

别再只盯着NRZ了!PAM4时代,你的CDR设计避坑指南(附眼图对比)

PAM4时代CDR设计实战&#xff1a;从NRZ平滑过渡的工程方法论 当112G SerDes逐渐成为数据中心互连的标配&#xff0c;PAM4信号处理能力已成为硬件工程师的必修课。与NRZ时代不同&#xff0c;PAM4带来的不仅是速率提升&#xff0c;更是一场信号完整性处理的范式转移。本文将揭示P…...

围棋AI分析工具LizzieYzy:从入门到精通的智能复盘神器

围棋AI分析工具LizzieYzy&#xff1a;从入门到精通的智能复盘神器 【免费下载链接】lizzieyzy LizzieYzy - GUI for Game of Go 项目地址: https://gitcode.com/gh_mirrors/li/lizzieyzy 还在为围棋复盘找不到问题所在而烦恼吗&#xff1f;LizzieYzy可能是你正在寻找的终…...

告别平台限制:三步解锁网易云音乐加密文件的自由播放体验

告别平台限制&#xff1a;三步解锁网易云音乐加密文件的自由播放体验 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 你是否曾经在网易云音乐下载了心爱的歌曲&#xff0c;却发现在手机、车载音响或其他播放器上无法播放&#xff1f…...

AI Agent技能生成实战:从文档网站到RAG知识库的自动化转换

1. 项目概述与核心价值最近在折腾AI智能体&#xff08;Agent&#xff09;的开发&#xff0c;发现一个挺普遍但又很棘手的问题&#xff1a;怎么让Agent快速、准确地“学会”使用某个工具或框架&#xff1f;很多优秀的开源项目、SaaS服务都提供了详尽的官方文档&#xff0c;但这些…...

Qwen2.5-VL-7B图文对话模型开箱即用:无需复杂配置,小白也能轻松上手

Qwen2.5-VL-7B图文对话模型开箱即用&#xff1a;无需复杂配置&#xff0c;小白也能轻松上手 1. 模型简介与核心能力 Qwen2.5-VL-7B-Instruct-GPTQ是一款基于通义千问团队最新研发的多模态大模型&#xff0c;专为图文对话任务优化。这个版本经过AngelSlim压缩技术处理&#xf…...

计算机专业专属!零基础网安完整学习路线,少走_90%_弯路

计算机专业专属&#xff01;零基础网安完整学习路线&#xff0c;少走 90% 弯路 很多计算机专业同学想入行网络安全&#xff0c;却苦于没有清晰规划&#xff0c;上课内容偏理论、实战薄弱&#xff0c;越学越迷茫。其实科班生有天然基础优势&#xff0c;只要找对学习顺序、抓准核…...

GetQzonehistory:5分钟快速备份QQ空间历史说说的完整免费方案

GetQzonehistory&#xff1a;5分钟快速备份QQ空间历史说说的完整免费方案 【免费下载链接】GetQzonehistory 获取QQ空间发布的历史说说 项目地址: https://gitcode.com/GitHub_Trending/ge/GetQzonehistory 你是否曾担心QQ空间里的青春记忆会随着时间流逝而消失&#xf…...

基于Java的LangChain4j智能客服实战:从零搭建企业级对话系统

告别“答非所问、越聊越懵”,用Java生态原生的AI框架让客服系统真正“听得懂、记得住、扩得快”。 一、传统客服系统的三大问题 在帮某金融客户做智能客服升级时,我第一次切身体会到传统客服系统的困境。用户问完“我的订单呢?”,紧跟着问“发货了吗?”,机器人却仿佛失忆…...