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

发布于 2024-11-19 22:06:28 字数 627 浏览 2 评论 0原文

我正在研究 Linux 内核版本 2.6.39.1,并正在开发块设备驱动程序。在这方面,我想将多个 struct bio 组合成一个 struct request ,然后将其添加到 request_queue 中以供处理设备驱动程序,即 -- scsi_request_fn()

我尝试使用struct bio->bi_next字段来链接我编写的多个struct bio,从而创建一个链接列表struct bio。当我调用submit_bio()将bio提交到块设备层进行I/O时,this BUG_ON() 被触发,因为代码期望 bio->bi_next NULL

在将多个struct bio发送到较低层进行服务之前,有没有办法将多个struct bio链接到单个struct request中?

I'm working on Linux kernel version 2.6.39.1, and am developing a block device driver. In this regard, I want to combine multiple struct bios into a single struct request, which is then added to the request_queue for processing by the device driver, namely -- scsi_request_fn().

I tried using the ->bi_next field of struct bio to link multiple struct bios that I have composed, thereby creating a linked list of struct bios. When I call submit_bio() to submit a bio to the block device layer for I/O, this BUG_ON() is triggered because the code expects bio->bi_next to be NULL.

Is there a way to link several struct bios into a single struct request before sending it to lower layers for servicing?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

仅此而已 2024-11-26 22:06:29

我不确定如何将多个 struct bio 串在一起,但您可能想看看 libsasaic94xx 驱动程序用于替代方法。文档不多,但是 libsas 文档 将其描述为

某些硬件(例如aic94xx)具有更多DMA能力
一次比主机内存中的一个任务(中断)要多。任务
收集器模式是 HA 的一项可选功能,支持
这在他们的硬件中。 (再次强调,它是完全可选的
即使您的硬件支持它。)

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

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

I'm not sure how to string multiple struct bio together, but you might want to take a look at the "task collector" implementation in libsas and the aic94xx driver for an alternate approach. There isn't much documentation, but the libsas documentation describes it as

Some hardware (e.g. aic94xx) has the capability to DMA more
than one task at a time (interrupt) from host memory. Task
Collector Mode is an optional feature for HAs which support
this in their hardware. (Again, it is completely optional
even if your hardware supports it.)

In Task Collector Mode, the SAS Layer would do natural
coalescing of tasks and at the appropriate moment it would
call your driver to DMA more than one task in a single HA
interrupt. DMBS may want to use this by insmod/modprobe
setting the lldd_max_execute_num to something greater than 1.

Effectively, this lets the block layer (a.k.a. BIO) remain unchanged, but multiple requests are accumulated at the driver layer and submitted together.

青瓷清茶倾城歌 2024-11-26 22:06:29

感谢您的回复,@ctuffli。我决定使用与所描述的结构类似的结构 在这里。基本上,我分配一个 struct packet_data ,它将包含指向所有 struct bio 的指针,这些指针应合并形成一个 struct bio (稍后上,一个结构请求)。此外,我还在这个struct packet_data中存储了一些驱动程序相关信息。接下来,我分配一个新的 struct bio(我们称之为“merged_bio”),复制原始 BIO 列表中的所有页面,然后创建 merged_bio->bi_private指向struct packet_data。最后一个 hack 将使我能够跟踪原始 BIO 列表,并且在 merged_bio 完成后,还可以调用 bio_endio() 来结束所有单独 BIO 上的 I/O。成功转移。

不确定这是否是最明智的方法,但它达到了我的预期! :^)

Thanks for the reply, @ctuffli. I've decided to use a structure similar to the one described here. Basically, I allocate a struct packet_data which would contain pointers to all struct bios that should be merged to form one single struct bio (and later on, one single struct request). In addition, I store some driver related information as well in this struct packet_data. Next, I allocate a new struct bio (lets call it "merged_bio"), copy all the pages from the list of original BIOs and then make the merged_bio->bi_private point to the struct packet_data. This last hack would allow me to keep track of the list of original BIOs, and also call bio_endio() to end I/O on all individual BIOs once the merged_bio has been successfully transferred.

Not sure if this is the smartest way to do this, but it does what I intended! :^)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文