首页 > 解决方案 > liburing / IORING_OP_PROVIDE_BUFFERS - 分配给读取操作的错误缓冲区

问题描述

我正在使用 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)。

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

有什么提示吗?

谢谢!

标签: clinuxnetworkinglinux-kernel

解决方案


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

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


推荐阅读