原本计划本节介绍request的分配,发现会涉及到数据组织从bio到sgl的映射,因此本节介绍数据的SGL组织方式。

在BLOCK层数据的组织形式为bio和request,通过这两个结构体就可以找到数据的位置。但若传输到SCSI层,硬盘位置用scsi command表示,内存中位置用scatterlist表示。本小节讲述scatterlist是如何将数据组织起来的。

1. scatterlist结构体

结构体scatterlis包含从CPU视角和设备视角看到的数据的地址和长度(包括页内偏移)。但其中page_link有两个特殊作用:(1)当第0 bit为1时即设置SG_CHAIN,表明当前sgl是链接sgl,只起链接到下一个sgl的作用,这个sgl不会指向数据;(2)当第1bit为1时即设置SG_END,表明当前sgl是最后一个sgl,这个sgl仍指向数据。当其他情况时指向数据对应的第一个页信息。

成员offset表示数据在页中的偏移。成员length表示数据的长度。

成员dma_address表示数据的DMA地址即设备看到的地址,成员dma_length表示数据的DMA长度。

2. SGL类型

SGL分为non-chained SGL和chained SGL。

Non-chained SGL表示多个sgl是连续的,内核这里对最大的non-chained SGL数目做限制,最大不超过SG_MAX_SINGLE_ALLOC,当申请的SGL个数超过此限制时会自动生成chained SGL。

Chained SGL存在多个的SGL链,每个SGL链中的SGL是连续的,其中每个SGL链(除了最后一个SGL链)最后一个SGL起链接作用。每个SGL链最大的SGL数目为SG_CHUNK_SIZE(128)。

3. SGL API介绍

函数sg_alloc_table()用来分配non-chained SGL(当申请的数目nents超过限制时,也会生成chained SGL)。

int sg_alloc_table(struct sg_table *table, unsigned int nents, gfp_t gfp_mask)

函数sg_alloc_table_chained()来分配chained SGL。其中nents为需要分配的SGL数目,first_chunk为sg_table中已经存在的SGL链,SGL链数目为first_chunk_nents。后面申请的SGL链与first_chunk相链。

​
int sg_alloc_table_chained(struct sg_table *table, int nents, struct scatterlist *first_chunk, unsigned nents_first_chunk)

两者最终会调用__sg_alloc_table()。这里处理四种情况:

(1)first_chunk = NULL, nents <= max_ents时

这种情况为sg_table,并没有提前分配SGL链,且需要分配SGL数目小于最大一次性能够分配的数目,此时通过alloc_fn()直接分配即可,生成non-chained SGL链。

(2)first_chunk = NULL, nents > max_ents时

这种情况为sg_table,并没有提前分配SGL链,且需要分配SGL数目大于最大一次性能够分配的数目,此时通过alloc_fn()会分配一个包含max_ents数目的SGL的SGL链,剩下的部分分配另一个SGL链,并将它们链起来,生成chained SGL链。

(3)first_chunk != NULL, nents <= max_ents时

这种情况为sg_table,提前分配SGL链, 且提前分配的SGL链上SGL数目满足需要的SGL链,此时会直接返回当前的sg_table。

(4)first_chunk != NULL, nents > max_ents时

这种情况为sg_table,提前分配SGL链, 但提前分配的SGL链上SGL数目不能够满足nents数目,此时需要通过alloc_fn()分配剩余的数目的SGL组成SGL链,并与提供分配的SGL链连接起来,生成chained SGL链。

4. SCSI命令的SGL

在SCSI层在分配request时默认内置了2个SGL(实际真正使用的仅1个,另一个做链接SGL使用),在申请时使用sg_alloc_table_chained(&cmd->sdb.table, nr_segs, cmd->sdb.table.sgl, SCSI_INLINE_SG_CNT)申请链式SGL。

下图为申请150个SGL的情况,其中内置2个SGL为第一个SGL链,这个是随request提前分配的(静态分配),后面两个SGL链是从sgpool中申请分配的(动态分配)。

BLOCK层代码分析(6)IO下发之SGL聚散列表相关推荐

  1. BLOCK层代码分析(10)IO下发之IO下发函数总结

    BLOCK层IO下发涉及直接下发,调度器,没有设置调度类型以及plug/unplug等,因此下发函数纷繁复杂,这里做介绍几个主要的函数. 前面介绍了函数blk_mq_try_issue_directl ...

  2. BLOCK层代码分析(9)IO下发之IO下发

    看着题目是不是很奇怪,想不出好的名字,就这样将就吧. 前面bio bounce过程,bio的切分和合并,request的获取是为IO请求下发做准备工作.当这些准备工作完成后,才进入到真正的IO下发过程 ...

  3. BLOCK层代码分析(1)数据的组织BIO

    对于BLOCK层,表示一个IO的数据结构为BIO和request.对于request在后续的章节中做介绍,这里只介绍与BIO相关的结构体. 1. bio/bio_vec结构体 bio结构体用于表示数据 ...

  4. BLOCK层代码分析(8)IO下发之plug/unplug机制

    前面bio bounce过程,bio的切分和合并,request的获取是为IO请求下发做准备工作.当这些准备工作完成后,才进入到真正的IO下发过程.之前在前面章节中介绍过,IO下发基本上有三条路径:经 ...

  5. BLOCK层代码分析(5)IO下发之BIO bounce过程

    若bio中存在数据处于高端内存时,外设无法在此高端内存上执行DMA,这里需要创建反弹缓冲区,将处于高端内存的缓存区和反弹缓冲区之间进行数据的复制.此过程称为bounce过程.但对于大部分驱动来説,并不 ...

  6. 三:Sensor SLPI层代码分析---

    三:Sensor SLPI层代码分析 在学习SLPI侧代码前我们先了解下SEE的registry&config. registry 放在/persist/sensors/registry/re ...

  7. perf-perf stat用户层代码分析

    perf_event 源码分析 前言 简单来说,perf是一种性能监测工具,它首先对通用处理器提供的performance counter进行编程,设定计数器阈值和事件,然后性能计数器就会在设定事件发 ...

  8. 20 | 散列表(下):为什么散列表和链表经常会一起使用?

    有两种数据结构,散列表和链表经常会被放在一起使用.常见的使用方式有: 用链表来实现 LRU 缓存淘汰算法,链表实现的 LRU 缓存淘汰算法的时间复杂度是 O(n),通过散列表可以将这个时间复杂度降低到 ...

  9. 四--RIL层代码分析--整个电话来访过程

    最近公司开发一个几百万的项目,要求重写系统RIL层,看了几个招聘信息,只要你会RIL层开发的,工资上w每个月不是梦,这是几天研究的成果,希望对大家有所帮助,兄弟们加油吧! 先来一个总的流程图: 拨出电 ...

最新文章

  1. Redis 笔记(02)— keys 键相关命令(查询数据库key数量、判断key是否存在、指定key过期时间、查看key类型、查看key剩余秒数、选择数据库、删除key、删除数据库)
  2. Java Execution Process
  3. 固件模块之间的关系 C语言里面的模块
  4. mysql与Json学习总结
  5. poj 1860 拓扑。。
  6. 什么是分布式系统中的幂等性
  7. golang 学习 (八)协程
  8. Linux下安装MyEclipse和Tomcat服务器详解,以及我安装过程中所出现的问题以及解决办法,并实现一个web小程序
  9. cortex-m0 专为支持OS的四个功能设计
  10. MyEclipse快捷键两篇文章
  11. Java实现mds降维_MDS降维方法的目标是要找到数据的低维表示,使得:
  12. mysql5.7bka_mysql 5.7中的MRR和BKA算法
  13. DOM、JDOM、DOM4J解析XML
  14. java robot api_用java Robot API 模拟实现类似按键精灵功能
  15. 简易鼠标模拟器 python
  16. 海量前端后台Java源码模板下载
  17. android 添加一维数组,Android:打造“万能”Adapter与ViewHolder
  18. 利用记事本编写html代码和word实现A4信笺纸(信签纸)电子版的两种设计法
  19. turf.js字典——查询turf库的所有方法及用途
  20. [SPI+DMA] 驱动WS2812B显示时钟

热门文章

  1. 1.5万字深度雄文:这才是实际工作中的竞品分析
  2. 哪一种开发语言有潜力有发展
  3. 1.在CentOS中搭建SVN服务器
  4. 客户主数据-供应商主数据-业务伙伴
  5. python制作课程表提醒_制作我的课程表(教案)
  6. 2012敏捷之旅苏州站活动将于2012年11月3日在西交利物浦大学举办
  7. 查找一段英文中各个单词出现的次数
  8. PAT | T1007 Red-black Tree
  9. java中结束进程的方法_java关闭Process
  10. 为什么Java是企业家的首选?