summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorPavel Begunkov <asml.silence@gmail.com>2021-02-23 22:17:20 +0000
committerJens Axboe <axboe@kernel.dk>2021-02-23 19:18:54 -0700
commite5547d2c5eb363bfac7632ba789ca834fa829650 (patch)
treec5c48ab77f57f37363acf586b97313bbcdc5e430 /fs
parent7c977a58dc83366e488c217fd88b1469d242bee5 (diff)
downloadlinux-e5547d2c5eb363bfac7632ba789ca834fa829650.tar.bz2
io_uring: fix locked_free_list caches_free()
Don't forget to zero locked_free_nr, it's not a disaster but makes it attempting to flush it with extra locking when there is nothing in the list. Also, don't traverse a potentially long list freeing requests under spinlock, splice the list and do it afterwards. Signed-off-by: Pavel Begunkov <asml.silence@gmail.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'fs')
-rw-r--r--fs/io_uring.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/fs/io_uring.c b/fs/io_uring.c
index 275ad84e8227..5c8e24274acf 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -8708,6 +8708,7 @@ static void io_req_cache_free(struct list_head *list, struct task_struct *tsk)
static void io_req_caches_free(struct io_ring_ctx *ctx, struct task_struct *tsk)
{
struct io_submit_state *submit_state = &ctx->submit_state;
+ struct io_comp_state *cs = &ctx->submit_state.comp;
mutex_lock(&ctx->uring_lock);
@@ -8717,12 +8718,13 @@ static void io_req_caches_free(struct io_ring_ctx *ctx, struct task_struct *tsk)
submit_state->free_reqs = 0;
}
- io_req_cache_free(&submit_state->comp.free_list, NULL);
-
spin_lock_irq(&ctx->completion_lock);
- io_req_cache_free(&submit_state->comp.locked_free_list, NULL);
+ list_splice_init(&cs->locked_free_list, &cs->free_list);
+ cs->locked_free_nr = 0;
spin_unlock_irq(&ctx->completion_lock);
+ io_req_cache_free(&cs->free_list, NULL);
+
mutex_unlock(&ctx->uring_lock);
}