5

我正在开发 Linux 内核版本 2.6.39.1,并且正在开发块设备驱动程序。对此,我想将多个struct bios 组合成一个 s struct request,然后request_queue由设备驱动添加到进行处理,即 -- scsi_request_fn()

我尝试使用->bi_nextof 字段struct bio来链接struct bio我已经组成的多个 s,从而创建了一个 s 的链表struct bio。当我打电话submit_bio()向 I/O 的块设备层提交 bio 时, BUG_ON()会被触发,因为代码期望bio->bi_nextNULL.

有没有办法在将几个s发送到较低层进行服务之前将其链接struct bio成一个?struct request

4

2 回答 2

1

我不确定如何将多个字符串串struct bio在一起,但您可能想看看 libsas 中的“任务收集器”实现和 aic94xx驱动程序以了解另一种方法。文档不多,但 libsas文档将其描述为

某些硬件(例如 aic94xx)能够从主机内存一次 DMA 多个任务(中断)。任务收集器模式是硬件中支持此功能的 HA 的可选功能。(同样,即使您的硬件支持它,它也是完全可选的。)

在任务收集器模式下,SAS 层会自然地 合并任务,并在适当的时候在一个 HA 中断中调用您的驱动程序对多个任务进行 DMA。DMBS 可能希望通过 insmod/modprobe 将 lldd_max_execute_num 设置为大于 1 的值来使用它。

实际上,这让块层(又名 BIO)保持不变,但多个请求在驱动层累积并一起提交。

于 2011-07-12T20:50:53.980 回答
1

感谢您的回复,@ctuffli。我决定使用类似于此处描述的结构。基本上,我分配了一个struct packet_data包含指向所有struct bios 的指针,这些 s 应该被合并成一个单一的struct bio(然后是一个单一的struct request)。另外,我也将一些驱动相关的信息存储在这个struct packet_data. 接下来,我分配一个新的struct bio(让我们称之为“merged_bio”),从原始 BIO 列表中复制所有页面,然后merged_bio->bi_private指向struct packet_data. 最后一次 hack 将允许我跟踪原始 BIO 列表,并在成功传输后调用bio_endio()结束所有单个 BIO 上的 I/O 。merged_bio

不确定这是否是最聪明的方法,但它符合我的意图!:^)

于 2011-07-19T02:33:05.373 回答