3

The man page for io_setup() says it will fail with EINVAL if the specified maxevents exceeds internal limits. Is there a way to find out what this "internal limit" is?

UBA
  • 81
  • 6

1 Answers1

2

That case is hardcoded in the kernel source, in fs/aio.c. And, it's pretty big!

    /* Prevent overflows */
    if (nr_events > (0x10000000U / sizeof(struct io_event))) {
        pr_debug("ENOMEM: nr_events too high\n");
        return ERR_PTR(-EINVAL);
    }

Typically, /proc/sys/fs/aio-max-nr is the one you need to worry about. That seems to be 65536 everywhere I've looked recently.

Source: https://github.com/torvalds/linux/blob/master/fs/aio.c

Mike Andrews
  • 3,045
  • 18
  • 28
  • 1
    Thank you for your response Mike. However, the issue is this: if the value in /proc/sys/fs/aio-max-nr is set to a huge number, for example 6000000, and 5000000 is passed to io_setup() it fails with -EINVAL. This is correct as 5000000 is over the limit. But how can I determine if this number is over the limit as setting a huge number in /proc/sys/fs/aio-max-nr did not complain? I do not think using an internal limit as a check in my code is a good idea. – UBA Jan 06 '20 at 16:35
  • Yeah, I see what you mean. That number isn't exposed anywhere. And, there doesn't seem to be any hard limit on how high it can be, or any reason for it being capped at the size it is. `nr_events` just figures into how much memory to allocate for the ringbuffer in `aio_setup_ring`. What I'd do if I really needed to operate at the edge of scale (and I'm too lazy to deal with a kernel patch) is first try `io_setup` with aio-max-nr. On `-EINVAL`, fall back to the known "current" maximum of 4194304. If that doesn't work, keep halving the number until success. – Mike Andrews Jan 06 '20 at 20:23