Skip to content

Commit dac6a0e

Browse files
committed
io_uring: ensure iopoll runs local task work as well
Combine the two checks we have for task_work running and whether or not we need to shuffle the mutex into one, so we unify how task_work is run in the iopoll loop. This helps ensure that local task_work is run when needed, and also optimizes that path to avoid a mutex shuffle if it's not needed. Signed-off-by: Jens Axboe <[email protected]>
1 parent 8ac5d85 commit dac6a0e

File tree

2 files changed

+26
-19
lines changed

2 files changed

+26
-19
lines changed

io_uring/io_uring.c

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1428,25 +1428,26 @@ static int io_iopoll_check(struct io_ring_ctx *ctx, long min)
14281428
* forever, while the workqueue is stuck trying to acquire the
14291429
* very same mutex.
14301430
*/
1431-
if (wq_list_empty(&ctx->iopoll_list)) {
1432-
u32 tail = ctx->cached_cq_tail;
1433-
1434-
mutex_unlock(&ctx->uring_lock);
1435-
ret = io_run_task_work_ctx(ctx);
1436-
mutex_lock(&ctx->uring_lock);
1437-
if (ret < 0)
1438-
break;
1439-
1440-
/* some requests don't go through iopoll_list */
1441-
if (tail != ctx->cached_cq_tail ||
1442-
wq_list_empty(&ctx->iopoll_list))
1443-
break;
1444-
}
1445-
1446-
if (task_work_pending(current)) {
1447-
mutex_unlock(&ctx->uring_lock);
1448-
io_run_task_work();
1449-
mutex_lock(&ctx->uring_lock);
1431+
if (wq_list_empty(&ctx->iopoll_list) ||
1432+
io_task_work_pending(ctx)) {
1433+
if (!llist_empty(&ctx->work_llist))
1434+
__io_run_local_work(ctx, true);
1435+
if (task_work_pending(current) ||
1436+
wq_list_empty(&ctx->iopoll_list)) {
1437+
u32 tail = ctx->cached_cq_tail;
1438+
1439+
mutex_unlock(&ctx->uring_lock);
1440+
ret = io_run_task_work();
1441+
mutex_lock(&ctx->uring_lock);
1442+
1443+
if (ret < 0)
1444+
break;
1445+
1446+
/* some requests don't go through iopoll_list */
1447+
if (tail != ctx->cached_cq_tail ||
1448+
wq_list_empty(&ctx->iopoll_list))
1449+
break;
1450+
}
14501451
}
14511452
ret = io_do_iopoll(ctx, !min);
14521453
if (ret < 0)

io_uring/io_uring.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,12 @@ static inline int io_run_task_work(void)
236236
return 0;
237237
}
238238

239+
static inline bool io_task_work_pending(struct io_ring_ctx *ctx)
240+
{
241+
return test_thread_flag(TIF_NOTIFY_SIGNAL) ||
242+
!wq_list_empty(&ctx->work_llist);
243+
}
244+
239245
static inline int io_run_task_work_ctx(struct io_ring_ctx *ctx)
240246
{
241247
int ret = 0;

0 commit comments

Comments
 (0)