“分散-聚集DMA”以及”scatterlist”
我们知道对磁盘的每个IO操作就是在磁盘与一些内存单元之间相互传送一些相邻扇区的内容。块设备驱动程序只要向磁盘控制器发送一些适当的命令(如前面我们所讲的scsi命令)就可以触发一次数据传送;一旦完成数据的传送,控制器就会发出一个中断通知块设备驱动程序。大多数情况,磁盘控制器直接采用DMA方式进行数据传送。
DMA
DMA全称就是直接内存访问,是一种硬件机制,它允许外围设备和主内存直接直接进行数据传输而不需要cpu的参与。
分散-聚集DMA
老式磁盘控制器在DMA传送时,磁盘必须与连续的内存单元相互传送数据。
新的磁盘控制器支持所谓的分散-聚集DMA传送方式:此种方式,磁盘可以与一些非连续的内存区相互传送数据。
启动一次分散-聚集DMA传送,块设备驱动需要向磁盘控制器发送:
- 要传送的起始磁盘扇区号和总的扇区数
- 内存区的描述符链表,其中链表的每项包含一个地址和一个长度(在内存页中位置以及大小)
分散/聚集映射
如果块设备驱动程序在实际传输过程中需要使用DMA,那么它可以遍历bio结构,并为
每个bio结构创建DMA映射,并将结果传递给设备。如果设备支持”分散-聚集DMA“
则有一个更简便高效的方法:
int blk_rq_map_sg(struct request_queue *q, struct request *rq, struct scatterlist *sglist)
从指定请求获得全部的段(段指bio中的每一个segment),然后把它们填写到给定表(list)中。内存中相邻的段将被合并在一个scatterlist中,返回值表示的是表中入口项的个数(表中有效元素个数),该函数使用第三个参数返回一个分散表。
在调用blk_rq_map_sg前,必须为分散