summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens Axboe <axboe@kernel.dk>2020-09-08 09:11:32 -0600
committerJens Axboe <axboe@kernel.dk>2020-09-30 20:32:34 -0600
commite95eee2dee7862f267a169b10d384c82f71010ce (patch)
tree34005d63a26e5f6f09b9ecc581a7502f3be6e2e8
parente8c2bc1fb6c9495b71efe7af476a351ccfba73c4 (diff)
io_uring: cap SQ submit size for SQPOLL with multiple rings
In the spirit of fairness, cap the max number of SQ entries we'll submit for SQPOLL if we have multiple rings. If we don't do that, we could be submitting tons of entries for one ring, while others are waiting to get service. The value of 8 is somewhat arbitrarily chosen as something that allows a fair bit of batching, without using an excessive time per ring. Signed-off-by: Jens Axboe <axboe@kernel.dk>
-rw-r--r--fs/io_uring.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/fs/io_uring.c b/fs/io_uring.c
index 268d8c526116..61a65a2b0a24 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -6690,7 +6690,7 @@ enum sq_ret {
};
static enum sq_ret __io_sq_thread(struct io_ring_ctx *ctx,
- unsigned long start_jiffies)
+ unsigned long start_jiffies, bool cap_entries)
{
unsigned long timeout = start_jiffies + ctx->sq_thread_idle;
struct io_sq_data *sqd = ctx->sq_data;
@@ -6758,6 +6758,10 @@ again:
finish_wait(&sqd->wait, &ctx->sqo_wait_entry);
io_ring_clear_wakeup_flag(ctx);
+ /* if we're handling multiple rings, cap submit size for fairness */
+ if (cap_entries && to_submit > 8)
+ to_submit = 8;
+
mutex_lock(&ctx->uring_lock);
if (likely(!percpu_ref_is_dying(&ctx->refs)))
ret = io_submit_sqes(ctx, to_submit);
@@ -6792,6 +6796,7 @@ static int io_sq_thread(void *data)
start_jiffies = jiffies;
while (!kthread_should_stop()) {
enum sq_ret ret = 0;
+ bool cap_entries;
/*
* Any changes to the sqd lists are synchronized through the
@@ -6804,6 +6809,8 @@ static int io_sq_thread(void *data)
if (unlikely(!list_empty(&sqd->ctx_new_list)))
io_sqd_init_new(sqd);
+ cap_entries = !list_is_singular(&sqd->ctx_list);
+
list_for_each_entry(ctx, &sqd->ctx_list, sqd_list) {
if (current->cred != ctx->creds) {
if (old_cred)
@@ -6811,7 +6818,7 @@ static int io_sq_thread(void *data)
old_cred = override_creds(ctx->creds);
}
- ret |= __io_sq_thread(ctx, start_jiffies);
+ ret |= __io_sq_thread(ctx, start_jiffies, cap_entries);
io_sq_thread_drop_mm();
}