io_uring 中的最大注册缓冲区大小

Max registered buffers size in io_uring

我试图通过 io_uring_register_buffers() 注册一组缓冲区,但我无法注册足够大的缓冲区。一个缓冲区大于 32768 字节或总大小大于 32768 的几个缓冲区都会导致 ENOMEM 错误。我读过一个缓冲区的最大缓冲区大小是 1GB。

有个例子:

#include <stdlib.h>
#include <stdio.h>
#include <liburing.h>

#define LEN 4096
#define CNT 9

int main()
{
    struct io_uring ring;
    struct iovec iov[CNT];
    char *buf;
    int res;

    if (io_uring_queue_init(64, &ring, 0) != 0)
        return -1;

    buf = malloc(LEN*CNT);

    for (int i = 0; i < CNT; i++) {
        iov[i].iov_base = buf + (i * LEN);
        iov[i].iov_len = LEN;
    }

    res = io_uring_register_buffers(&ring, iov, CNT);
    printf("%d\n", res);

    io_uring_queue_exit(&ring);

    return 0;
}

如果我将 CNT 定义为 9,则会出现 ENOMEM 错误。怎么了?

我从一个 liburing 贡献者那里得到了 an answer

Pavel Begunkov(沉默):

You hit RLIMIT_MEMLOCK. The limit is usually 64KB, but I guess you stumble on 32KB because malloc returns a not aligned chunk, but registration works with pages, so for each buffer it registers 2 adjacent pages, that's twice as much.

在我的系统中,非特权用户的硬限制是 64kB。使用 aligned_alloc(4096, LENCNT) 而不是 malloc(LENCNT),我有 64kB 的限制。

所以至少有两种方法:

  1. 在系统设置中为非特权用户增加RLIMIT_MEMLOCK;
  2. 以 root 用户身份执行程序。

我认为另一种选择是分配和注册一个大缓冲区,然后简单地在提交队列条目中提供缓冲区的偏移量。