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

blk_mq_alloc_tag_set函数struct blk_mq_tag_set结构体学习

struct blk_mq_tag_set结构体

include/linux/blk-mq.h

struct blk_mq_tag_set {unsigned int		*mq_map;const struct blk_mq_ops	*ops;unsigned int		nr_hw_queues;unsigned int		queue_depth;	/* max hw supported */unsigned int		reserved_tags;unsigned int		cmd_size;	/* per-request extra data */int			numa_node;unsigned int		timeout;unsigned int		flags;		/* BLK_MQ_F_* */void			*driver_data;struct blk_mq_tags	**tags;struct mutex		tag_list_lock;struct list_head	tag_list;
};

后面再分析每个成员的作用。

blk_mq_alloc_tag_set函数分析

/** Alloc a tag set to be associated with one or more request queues.* May fail with EINVAL for various error conditions. May adjust the* requested depth down, if it's too large. In that case, the set* value will be stored in set->queue_depth.*/
int blk_mq_alloc_tag_set(struct blk_mq_tag_set *set)
{int ret;//...set->tags = kcalloc_node(nr_cpu_ids, sizeof(struct blk_mq_tags *),GFP_KERNEL, set->numa_node);if (!set->tags)return -ENOMEM;ret = -ENOMEM;set->mq_map = kcalloc_node(nr_cpu_ids, sizeof(*set->mq_map),GFP_KERNEL, set->numa_node);if (!set->mq_map)goto out_free_tags;ret = blk_mq_update_queue_map(set);if (ret)goto out_free_mq_map;ret = blk_mq_alloc_rq_maps(set);if (ret)goto out_free_mq_map;mutex_init(&set->tag_list_lock);INIT_LIST_HEAD(&set->tag_list);return 0;out_free_mq_map:kfree(set->mq_map);set->mq_map = NULL;
out_free_tags:kfree(set->tags);set->tags = NULL;return ret;
}
EXPORT_SYMBOL(blk_mq_alloc_tag_set);

这个函数一进来的话先是对其,这两个成员的合法性做一个检查,这两个成员的值,一般是从硬件获取的,在调用该函数时已经赋值了。

nr_hw_queues
queue_depth

然后是tags成员的赋值,申请内存,它是一个二级指针,申请的元素个数是cpu个数,可以理解是一个指针数组,数组里的每一个成员都是一个指针,例如,下面的这个小demo,

#include<stdio.h>
#include<stdlib.h>int main(int argc, char **argv)
{int **p;int i, j, x, y;p = malloc(sizeof(int) * 4);p[0] = &x;p[1] = &y;x = 10;y = 20;printf("p = %d\n", *(*(p + 0)));return 0;
}

然后是mq_map这个成员,它申请的内存空间也是cpu的个数。

blk_mq_update_queue_map

然后深入到这个函数,

static int blk_mq_update_queue_map(struct blk_mq_tag_set *set)
{if (set->ops->map_queues) {/** transport .map_queues is usually done in the following* way:** for (queue = 0; queue < set->nr_hw_queues; queue++) {* 	mask = get_cpu_mask(queue)* 	for_each_cpu(cpu, mask)* 		set->mq_map[cpu] = queue;* }** When we need to remap, the table has to be cleared for* killing stale mapping since one CPU may not be mapped* to any hw queue.*/blk_mq_clear_mq_map(set);return set->ops->map_queues(set);} elsereturn blk_mq_map_queues(set);
}

继续,

int blk_mq_map_queues(struct blk_mq_tag_set *set)
{unsigned int *map = set->mq_map;unsigned int nr_queues = set->nr_hw_queues;unsigned int cpu, first_sibling;for_each_possible_cpu(cpu) {/** First do sequential mapping between CPUs and queues.* In case we still have CPUs to map, and we have some number of* threads per cores then map sibling threads to the same queue for* performace optimizations.*/if (cpu < nr_queues) {map[cpu] = cpu_to_queue_index(nr_queues, cpu);} else {first_sibling = get_first_sibling(cpu);if (first_sibling == cpu)map[cpu] = cpu_to_queue_index(nr_queues, cpu);elsemap[cpu] = map[first_sibling];}}return 0;
}
EXPORT_SYMBOL_GPL(blk_mq_map_queues);

前面说了mq_map其实是一个指针,这里终于看到它赋值的地方了,根据注释不难看出,这个指针(其实就是个一维数组),的下标是cpu编号,然后每个数组元素的值是硬件队列的编号。到这里这个函数就结束了,其实功能就是给mq_map赋值的。

blk_mq_alloc_rq_maps

然后到blk_mq_alloc_rq_maps这个函数的分析
待后续。。。。。

http://www.lryc.cn/news/112424.html

相关文章:

  • Windows搭建Snort环境及使用方式
  • Android network — iptables四表五链
  • 【C++从0到王者】第十六站:stack和queue的使用
  • centos7 部署Tomcat和jpress应用
  • Unity Shader:常用的C#与shader交互的方法
  • luajit 使用 clang编译的坑
  • [SWPUCTF 2021 新生赛]Do_you_know_http
  • web前端之CSS
  • HarmonyOS元服务开发实践:桌面卡片字典
  • xLua学习
  • ​Web3到底是个啥?
  • pycharm、idea、golang等JetBrains其他IDE修改行分隔符(换行符)
  • ThinkPHP函数深度解析
  • 【java】【maven】【高级】MAVEN聚合继承属性等
  • LeetCode150道面试经典题-合并两个有序数组(简单)
  • 记录 运维三剑客一件部署的的docker-compose,yml文件
  • Xposed框架开发
  • 2.13 Android ebpf非网络相关帮助函数API汇总(十二 本章完)
  • 关于游戏的笔记
  • vue diff 前后缀+最长递增子序列算法
  • 【Python】Locust持续优化:InfluxDB与Grafana实现数据持久化与可视化分析
  • 数组模拟循环链表
  • 第三章 图论 No.5最小生成树之虚拟源点,完全图与次小生成树
  • RESTful API的讲解以及用PHP实现RESTful API
  • Spring中@Component和@Bean的区别
  • 【问题解决】mysql 数据库字符串分割之后多行输出方法
  • flutter开发实战-时间显示刚刚几分钟前几小时前
  • 导出LLaMA等LLM模型为onnx
  • 回顾 OWASP 机器学习十大风险
  • ENSP软件的基本使用命令(第三十一课)