Search code examples
linuxio-uring

Max registered buffers size in io_uring


I've tried to register a set of buffers by io_uring_register_buffers() but I couldn't register buffers big enough. Either one buffer bigger than 32768 bytes or a few buffers with the total size bigger 32768 lead to the ENOMEM error. I've read the maximum buffer size is 1GB for one buffer.

There is an example:

#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;
}

If I define CNT as 9, I have ENOMEM error. What is wrong?


Solution

  • I've got an answer from a liburing contributor.

    Pavel Begunkov (isilence):

    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.

    In my system the hard limit for unprivileged users is 64kB. Using aligned_alloc(4096, LENCNT) instead malloc(LENCNT), I have 64kB limit.

    So there are at least two ways:

    1. to increase RLIMIT_MEMLOCK for unprivileged users in system settings;
    2. to execute the program as root user.