我正在研究Linux内核版本2.6.39.1,正在开发一个块设备驱动程序。在这方面,我想将多个struct bio
合并为一个struct request
,然后将其添加到request_queue
以供设备驱动程序处理,即 - scsi_request_fn()
我尝试使用->bi_next
的{{1}}字段链接我编写的多个struct bio
,从而创建struct bio
s的链接列表。当我致电struct bio
向块设备层提交I / O时,会触发this submit_bio()
,因为代码期望BUG_ON()
为bio->bi_next
在将多个NULL
发送到较低层以进行维修之前,有没有办法将多个struct bio
链接到一个struct request
?
答案 0 :(得分:1)
我不确定如何将多个struct bio
串在一起,但您可能需要查看libsas中的“任务收集器”实现和aic94xx驱动程序替代方法。文档不多,但libsas documentation将其描述为
某些硬件(例如aic94xx)具有更多DMA功能 一次一个任务(中断)从主机内存。任务 收集器模式是支持的HA的可选功能 这在他们的硬件中。 (同样,它完全是可选的 即使您的硬件支持它。)
在任务收集器模式下,SAS层将执行自然 合并任务,并在适当的时候 在单个HA中调用您的驱动程序DMA多个任务 打断。 DMBS可能希望通过insmod / modprobe使用它 将lldd_max_execute_num设置为大于1的值。
实际上,这使得阻止层(a.k.a. BIO)保持不变,但是在驱动程序层累积了多个请求并一起提交。
答案 1 :(得分:1)
感谢你回复@ctuffli。我决定使用类似于here描述的结构。基本上,我分配一个struct packet_data
,其中包含指向应该合并为一个struct bio
(以及之后的单个struct bio
)的所有struct request
的指针。此外,我还在此struct packet_data
中存储了一些与驱动程序相关的信息。接下来,我分配一个新的struct bio
(让我们称之为" merged_bio"),复制原始BIO列表中的所有页面,然后将merged_bio->bi_private
指向{{1 }}。最后一次攻击可以让我跟踪原始BIO列表,并在struct packet_data
成功传输后调用bio_endio()
来终止所有单个BIO上的I / O.
不确定这是否是最明智的方法,但它确实符合我的意图! :^)