如何将多个struct BIO组合成一个struct请求?

时间:2011-07-12 14:23:20

标签: linux linux-kernel storage linux-device-driver block-device

我正在研究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

2 个答案:

答案 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.

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