为什么 io_submit(..., nr, ...) 提交的请求可能比 nr 少?

Why io_submit(..., nr, ...) might submit less requests than nr?

我正在使用 io_submit(..., nr, ...),nr 最多为 128,但提交的请求通常较少。

根据手册 IO_SUBMIT(2),这是合法的,但我想知道:为什么?另外,有没有办法立即知道提交了哪个请求 - 无需检查 io_getevents()?

来自手册:

On success, io_submit() returns the number of iocbs submitted (which may be less than nr, or 0 if nr is zero). For the failure return, see NOTES.

您提交的结果较少的一个可能原因是您已达到 128 个未完成请求的限制。也许你用 128 调用了 io_submit,然后在所有 128 个请求完成之前再次调用它?请参阅设备的 sysfs 中的 nr_requests 条目以了解其愿意处理的请求数量限制:

# cat /sys/block/sda/queue/nr_requests
128

由您的代码跟踪有多少未完成的请求,并避免尝试调用 io_submit 时发出的请求数量超过此限制。

现在,这可能不是您的呼叫提交的请求少于请求的原因。如果查看 the kernel source, in fs/aio.c,您可以在 __io_submit_one 中看到所有可能触发短响应的失败条件。其中一个请求可能存在参数问题,或者它可能无法为 kiocb 分配 slab 内存,等等。但最有可能的是 aio_get_req 由于 nr_requests 而失败队列深度限制。

如果您查看同一文件中的 SYSCALL_DEFINE3(io_submit...,您会发现很容易找出哪些请求未提交。它只是您传递给 io_submit 的数组中的位置。例如,如果 io_submit returns 5,那么您知道您在数组索引 0-4 中提交的请求已提交。 5 到 nr - 1 之间的任何内容都没有提交。