Skip to content

Commit

Permalink
Add support for ring resizing
Browse files Browse the repository at this point in the history
io_uring_resize_rings() support resizing the SQ and CQ rings, where
the most useful case here is resizing the CQ ring. This can be useful
for cases where users of a ring don't have a good idea of how busy it
will be. Rather than start with a big ring, they can start small for
the most common use cases, and enlarge it if needed if/when overflows
are seen.

Usage:

struct io_uring_params p = { };

p.sq_entries = new_sq_entries;
p.cq_entries = new_cq_entries;

io_uring_resize_rings(ring, &p);

where 'new_sq_entries' is the new value for the size of the SQ ring,
and 'new_cq_entries' is the new value for the size of the CQ ring.

Signed-off-by: Jens Axboe <[email protected]>
  • Loading branch information
axboe committed Oct 21, 2024
1 parent 03aab18 commit 37dd533
Show file tree
Hide file tree
Showing 7 changed files with 53 additions and 6 deletions.
1 change: 1 addition & 0 deletions src/include/liburing.h
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ int io_uring_submit_and_wait_min_timeout(struct io_uring *ring,
unsigned min_wait,
sigset_t *sigmask);

int io_uring_resize_rings(struct io_uring *ring, struct io_uring_params *p);
int io_uring_clone_buffers(struct io_uring *dst, struct io_uring *src);
int io_uring_register_buffers(struct io_uring *ring, const struct iovec *iovecs,
unsigned nr_iovecs);
Expand Down
2 changes: 2 additions & 0 deletions src/include/liburing/io_uring.h
Original file line number Diff line number Diff line change
Expand Up @@ -612,6 +612,8 @@ enum io_uring_register_op {
/* clone registered buffers from source ring to current ring */
IORING_REGISTER_CLONE_BUFFERS = 30,

IORING_REGISTER_RESIZE_RINGS = 33,

/* this goes last */
IORING_REGISTER_LAST,

Expand Down
1 change: 1 addition & 0 deletions src/liburing-ffi.map
Original file line number Diff line number Diff line change
Expand Up @@ -214,4 +214,5 @@ LIBURING_2.8 {
io_uring_prep_cmd_discard;
io_uring_prep_open;
io_uring_prep_open_direct;
io_uring_resize_rings;
} LIBURING_2.7;
1 change: 1 addition & 0 deletions src/liburing.map
Original file line number Diff line number Diff line change
Expand Up @@ -102,4 +102,5 @@ LIBURING_2.8 {
io_uring_submit_and_wait_min_timeout;
io_uring_wait_cqes_min_timeout;
io_uring_clone_buffers;
io_uring_resize_rings;
} LIBURING_2.7;
36 changes: 36 additions & 0 deletions src/register.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "lib.h"
#include "syscall.h"
#include "liburing.h"
#include "setup.h"
#include "int_flags.h"
#include "liburing/compat.h"
#include "liburing/io_uring.h"
Expand Down Expand Up @@ -408,3 +409,38 @@ int io_uring_clone_buffers(struct io_uring *dst, struct io_uring *src)

return do_register(dst, IORING_REGISTER_CLONE_BUFFERS, &buf, 1);
}

int io_uring_resize_rings(struct io_uring *ring, struct io_uring_params *p)
{
unsigned sq_entries;
int ret;

ret = do_register(ring, IORING_REGISTER_RESIZE_RINGS, p, 1);
if (ret < 0)
return ret;

io_uring_unmap_rings(&ring->sq, &ring->cq);
if (!(p->flags & IORING_SETUP_NO_MMAP)) {
ret = io_uring_mmap(ring->ring_fd, p, &ring->sq, &ring->cq);
if (ret)
return ret;
} else {
io_uring_setup_ring_pointers(p, &ring->sq, &ring->cq);
}

/*
* Directly map SQ slots to SQEs
*/
sq_entries = ring->sq.ring_entries;

if (!(p->flags & IORING_SETUP_NO_SQARRAY)) {
unsigned *sq_array;
unsigned index;

sq_array = ring->sq.array;
for (index = 0; index < sq_entries; index++)
sq_array[index] = index;
}

return 0;
}
12 changes: 6 additions & 6 deletions src/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,17 +59,17 @@ static int get_sq_cq_entries(unsigned entries, struct io_uring_params *p,
return 0;
}

static void io_uring_unmap_rings(struct io_uring_sq *sq, struct io_uring_cq *cq)
void io_uring_unmap_rings(struct io_uring_sq *sq, struct io_uring_cq *cq)
{
if (sq->ring_sz)
__sys_munmap(sq->ring_ptr, sq->ring_sz);
if (cq->ring_ptr && cq->ring_sz && cq->ring_ptr != sq->ring_ptr)
__sys_munmap(cq->ring_ptr, cq->ring_sz);
}

static void io_uring_setup_ring_pointers(struct io_uring_params *p,
struct io_uring_sq *sq,
struct io_uring_cq *cq)
void io_uring_setup_ring_pointers(struct io_uring_params *p,
struct io_uring_sq *sq,
struct io_uring_cq *cq)
{
sq->khead = sq->ring_ptr + p->sq_off.head;
sq->ktail = sq->ring_ptr + p->sq_off.tail;
Expand All @@ -95,8 +95,8 @@ static void io_uring_setup_ring_pointers(struct io_uring_params *p,
cq->ring_entries = *cq->kring_entries;
}

static int io_uring_mmap(int fd, struct io_uring_params *p,
struct io_uring_sq *sq, struct io_uring_cq *cq)
int io_uring_mmap(int fd, struct io_uring_params *p, struct io_uring_sq *sq,
struct io_uring_cq *cq)
{
size_t size;
int ret;
Expand Down
6 changes: 6 additions & 0 deletions src/setup.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,11 @@
int __io_uring_queue_init_params(unsigned entries, struct io_uring *ring,
struct io_uring_params *p, void *buf,
size_t buf_size);
void io_uring_unmap_rings(struct io_uring_sq *sq, struct io_uring_cq *cq);
int io_uring_mmap(int fd, struct io_uring_params *p, struct io_uring_sq *sq,
struct io_uring_cq *cq);
void io_uring_setup_ring_pointers(struct io_uring_params *p,
struct io_uring_sq *sq,
struct io_uring_cq *cq);

#endif

0 comments on commit 37dd533

Please sign in to comment.