Skip to content

Commit 4d24432

Browse files
committed
Merge tag 'io_uring-6.1-2022-10-28' of git://git.kernel.dk/linux
Pull io_uring fix from Jens Axboe: "Just a fix for a locking regression introduced with the deferred task_work running from this merge window" * tag 'io_uring-6.1-2022-10-28' of git://git.kernel.dk/linux: io_uring: unlock if __io_run_local_work locked inside io_uring: use io_run_local_work_locked helper
2 parents 3c339db + b302676 commit 4d24432

File tree

2 files changed

+16
-8
lines changed

2 files changed

+16
-8
lines changed

io_uring/io_uring.c

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1173,7 +1173,7 @@ static void __cold io_move_task_work_from_local(struct io_ring_ctx *ctx)
11731173
}
11741174
}
11751175

1176-
int __io_run_local_work(struct io_ring_ctx *ctx, bool locked)
1176+
int __io_run_local_work(struct io_ring_ctx *ctx, bool *locked)
11771177
{
11781178
struct llist_node *node;
11791179
struct llist_node fake;
@@ -1192,7 +1192,7 @@ int __io_run_local_work(struct io_ring_ctx *ctx, bool locked)
11921192
struct io_kiocb *req = container_of(node, struct io_kiocb,
11931193
io_task_work.node);
11941194
prefetch(container_of(next, struct io_kiocb, io_task_work.node));
1195-
req->io_task_work.func(req, &locked);
1195+
req->io_task_work.func(req, locked);
11961196
ret++;
11971197
node = next;
11981198
}
@@ -1208,7 +1208,7 @@ int __io_run_local_work(struct io_ring_ctx *ctx, bool locked)
12081208
goto again;
12091209
}
12101210

1211-
if (locked)
1211+
if (*locked)
12121212
io_submit_flush_completions(ctx);
12131213
trace_io_uring_local_work_run(ctx, ret, loops);
12141214
return ret;
@@ -1225,7 +1225,7 @@ int io_run_local_work(struct io_ring_ctx *ctx)
12251225

12261226
__set_current_state(TASK_RUNNING);
12271227
locked = mutex_trylock(&ctx->uring_lock);
1228-
ret = __io_run_local_work(ctx, locked);
1228+
ret = __io_run_local_work(ctx, &locked);
12291229
if (locked)
12301230
mutex_unlock(&ctx->uring_lock);
12311231

@@ -1446,8 +1446,7 @@ static int io_iopoll_check(struct io_ring_ctx *ctx, long min)
14461446
io_task_work_pending(ctx)) {
14471447
u32 tail = ctx->cached_cq_tail;
14481448

1449-
if (!llist_empty(&ctx->work_llist))
1450-
__io_run_local_work(ctx, true);
1449+
(void) io_run_local_work_locked(ctx);
14511450

14521451
if (task_work_pending(current) ||
14531452
wq_list_empty(&ctx->iopoll_list)) {

io_uring/io_uring.h

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ enum {
2727
struct io_uring_cqe *__io_get_cqe(struct io_ring_ctx *ctx, bool overflow);
2828
bool io_req_cqe_overflow(struct io_kiocb *req);
2929
int io_run_task_work_sig(struct io_ring_ctx *ctx);
30-
int __io_run_local_work(struct io_ring_ctx *ctx, bool locked);
30+
int __io_run_local_work(struct io_ring_ctx *ctx, bool *locked);
3131
int io_run_local_work(struct io_ring_ctx *ctx);
3232
void io_req_complete_failed(struct io_kiocb *req, s32 res);
3333
void __io_req_complete(struct io_kiocb *req, unsigned issue_flags);
@@ -277,9 +277,18 @@ static inline int io_run_task_work_ctx(struct io_ring_ctx *ctx)
277277

278278
static inline int io_run_local_work_locked(struct io_ring_ctx *ctx)
279279
{
280+
bool locked;
281+
int ret;
282+
280283
if (llist_empty(&ctx->work_llist))
281284
return 0;
282-
return __io_run_local_work(ctx, true);
285+
286+
locked = true;
287+
ret = __io_run_local_work(ctx, &locked);
288+
/* shouldn't happen! */
289+
if (WARN_ON_ONCE(!locked))
290+
mutex_lock(&ctx->uring_lock);
291+
return ret;
283292
}
284293

285294
static inline void io_tw_lock(struct io_ring_ctx *ctx, bool *locked)

0 commit comments

Comments
 (0)