io_uring: add support for IORING_SETUP_CLAMP
Some applications like to start small in terms of ring size, and then ramp up as needed. This is a bit tricky to do currently, since we don't advertise the max ring size. This adds IORING_SETUP_CLAMP. If set, and the values for SQ or CQ ring size exceed what we support, then clamp them at the max values instead of returning -EINVAL. Since we return the chosen ring sizes after setup, no further changes are needed on the application side. io_uring already changes the ring sizes if the application doesn't ask for power-of-two sizes, for example. Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
@@ -6234,8 +6234,13 @@ static int io_uring_create(unsigned entries, struct io_uring_params *p)
|
|||||||
bool account_mem;
|
bool account_mem;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!entries || entries > IORING_MAX_ENTRIES)
|
if (!entries)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
if (entries > IORING_MAX_ENTRIES) {
|
||||||
|
if (!(p->flags & IORING_SETUP_CLAMP))
|
||||||
|
return -EINVAL;
|
||||||
|
entries = IORING_MAX_ENTRIES;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Use twice as many entries for the CQ ring. It's possible for the
|
* Use twice as many entries for the CQ ring. It's possible for the
|
||||||
@@ -6252,8 +6257,13 @@ static int io_uring_create(unsigned entries, struct io_uring_params *p)
|
|||||||
* to a power-of-two, if it isn't already. We do NOT impose
|
* to a power-of-two, if it isn't already. We do NOT impose
|
||||||
* any cq vs sq ring sizing.
|
* any cq vs sq ring sizing.
|
||||||
*/
|
*/
|
||||||
if (p->cq_entries < p->sq_entries || p->cq_entries > IORING_MAX_CQ_ENTRIES)
|
if (p->cq_entries < p->sq_entries)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
if (p->cq_entries > IORING_MAX_CQ_ENTRIES) {
|
||||||
|
if (!(p->flags & IORING_SETUP_CLAMP))
|
||||||
|
return -EINVAL;
|
||||||
|
p->cq_entries = IORING_MAX_CQ_ENTRIES;
|
||||||
|
}
|
||||||
p->cq_entries = roundup_pow_of_two(p->cq_entries);
|
p->cq_entries = roundup_pow_of_two(p->cq_entries);
|
||||||
} else {
|
} else {
|
||||||
p->cq_entries = 2 * p->sq_entries;
|
p->cq_entries = 2 * p->sq_entries;
|
||||||
@@ -6345,7 +6355,8 @@ static long io_uring_setup(u32 entries, struct io_uring_params __user *params)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (p.flags & ~(IORING_SETUP_IOPOLL | IORING_SETUP_SQPOLL |
|
if (p.flags & ~(IORING_SETUP_IOPOLL | IORING_SETUP_SQPOLL |
|
||||||
IORING_SETUP_SQ_AFF | IORING_SETUP_CQSIZE))
|
IORING_SETUP_SQ_AFF | IORING_SETUP_CQSIZE |
|
||||||
|
IORING_SETUP_CLAMP))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
ret = io_uring_create(entries, &p);
|
ret = io_uring_create(entries, &p);
|
||||||
|
@@ -61,6 +61,7 @@ struct io_uring_sqe {
|
|||||||
#define IORING_SETUP_SQPOLL (1U << 1) /* SQ poll thread */
|
#define IORING_SETUP_SQPOLL (1U << 1) /* SQ poll thread */
|
||||||
#define IORING_SETUP_SQ_AFF (1U << 2) /* sq_thread_cpu is valid */
|
#define IORING_SETUP_SQ_AFF (1U << 2) /* sq_thread_cpu is valid */
|
||||||
#define IORING_SETUP_CQSIZE (1U << 3) /* app defines CQ size */
|
#define IORING_SETUP_CQSIZE (1U << 3) /* app defines CQ size */
|
||||||
|
#define IORING_SETUP_CLAMP (1U << 4) /* clamp SQ/CQ ring sizes */
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
IORING_OP_NOP,
|
IORING_OP_NOP,
|
||||||
|
Reference in New Issue
Block a user