liburing / IORING_OP_PROVIDE_BUFFERS - 分配给读取操作的缓冲区错误

liburing / IORING_OP_PROVIDE_BUFFERS - wrong buffer assigned to read op

我正在玩 liburing 和 io_uring,前者是从 master 分支构建的,而后者我使用的是内核 5.8.0-rc3。

我也遇到了我将在以前版本的内核(5.7.6、5.8.0-rc1)上解释的问题。

使用提供缓冲区的测试看起来像预期的那样工作。

我正在尝试使用 IORING_FEAT_FAST_POLLIORING_OP_PROVIDE_BUFFERS 实现网络 tcp/ip 服务器我正在使用 https://github.com/frevib/io_uring-echo-server 作为代码参考。

我面临的问题是缓冲区 ID 始终设置为最后一个注册缓冲区,但我可以看到内核使用的实际缓冲区不是那个。

我已将注册缓冲区的数量减少到 10 个并添加了一些调试信息,它现在正在打印所有缓冲区的内容

在收到来自服务器的第一个 RECV 后,我在 cqe->flags >> 16 中获取了包含数据的缓冲区的 ID,它是列表的最后一个,我可以看到它包含数据,但是在第二个RECV 内核现在使用了缓冲区 ID 0(第一个),但是 cqe->flags >> 16 仍然包含最后一个的 ID。

原因是 io_uring_prep_provide_buffers 的调用,实际上在第二次调用时出现了问题。

出于好奇,我也尝试使用

一个一个地注册缓冲区
    for(uint16_t i = 0; i<MAX_CONNECTIONS; i++) {
        sqe = io_uring_get_sqe(&ring);
        io_uring_prep_provide_buffers(sqe, bufs, MAX_MESSAGE_LEN, 1, group_id, i);
    }

而不是

    io_uring_prep_provide_buffers(sqe, bufs, MAX_MESSAGE_LEN, MAX_CONNECTIONS, group_id, 0);

问题立即开始。

我还完全禁用了已释放缓冲区的重新注册,一切都按预期工作(我注释掉了函数 add_provide_buf 的调用)。

从文档中可以看出,在选择缓冲区后,如果可以自由使用,则期望将其添加回去,但显然这是导致问题的原因。

有什么提示吗?

谢谢!

重新注册缓冲区的代码中存在错误:https://github.com/frevib/io_uring-echo-server/commit/aa6f2a09ca14c6aa17779a22343b9e7d4b3c7994

检查最新的 master 分支,它现在应该可以工作了:https://github.com/frevib/io_uring-echo-server