Skip to content

Commit 5d4740f

Browse files
committed
Merge tag 'io_uring-6.2-2022-12-19' of git://git.kernel.dk/linux
Pull io_uring fixes from Jens Axboe: - Improve the locking for timeouts. This was originally queued up for the initial pull, but I messed up and it got missed. (Pavel) - Fix an issue with running task_work from the wait path, causing some inefficiencies (me) - Add a clear of ->free_iov upfront in the 32-bit compat data importing, so we ensure that it's always sane at completion time (me) - Use call_rcu_hurry() for the eventfd signaling (Dylan) - Ordering fix for multishot recv completions (Pavel) - Add the io_uring trace header to the MAINTAINERS entry (Ammar) * tag 'io_uring-6.2-2022-12-19' of git://git.kernel.dk/linux: MAINTAINERS: io_uring: Add include/trace/events/io_uring.h io_uring/net: fix cleanup after recycle io_uring/net: ensure compat import handlers clear free_iov io_uring: include task_work run after scheduling in wait for events io_uring: don't use TIF_NOTIFY_SIGNAL to test for availability of task_work io_uring: use call_rcu_hurry if signaling an eventfd io_uring: fix overflow handling regression io_uring: ease timeout flush locking requirements io_uring: revise completion_lock locking io_uring: protect cq_timeouts with timeout_lock
2 parents 0a92481 + 5ad70eb commit 5d4740f

File tree

6 files changed

+44
-30
lines changed

6 files changed

+44
-30
lines changed

MAINTAINERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10878,6 +10878,7 @@ T: git git://git.kernel.dk/liburing
1087810878
F: io_uring/
1087910879
F: include/linux/io_uring.h
1088010880
F: include/linux/io_uring_types.h
10881+
F: include/trace/events/io_uring.h
1088110882
F: include/uapi/linux/io_uring.h
1088210883
F: tools/io_uring/
1088310884

io_uring/io_uring.c

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -538,7 +538,7 @@ static void io_eventfd_signal(struct io_ring_ctx *ctx)
538538
} else {
539539
atomic_inc(&ev_fd->refs);
540540
if (!atomic_fetch_or(BIT(IO_EVENTFD_OP_SIGNAL_BIT), &ev_fd->ops))
541-
call_rcu(&ev_fd->rcu, io_eventfd_ops);
541+
call_rcu_hurry(&ev_fd->rcu, io_eventfd_ops);
542542
else
543543
atomic_dec(&ev_fd->refs);
544544
}
@@ -572,12 +572,11 @@ static void io_eventfd_flush_signal(struct io_ring_ctx *ctx)
572572

573573
void __io_commit_cqring_flush(struct io_ring_ctx *ctx)
574574
{
575-
if (ctx->off_timeout_used || ctx->drain_active) {
575+
if (ctx->off_timeout_used)
576+
io_flush_timeouts(ctx);
577+
if (ctx->drain_active) {
576578
spin_lock(&ctx->completion_lock);
577-
if (ctx->off_timeout_used)
578-
io_flush_timeouts(ctx);
579-
if (ctx->drain_active)
580-
io_queue_deferred(ctx);
579+
io_queue_deferred(ctx);
581580
spin_unlock(&ctx->completion_lock);
582581
}
583582
if (ctx->has_evfd)
@@ -597,6 +596,18 @@ static inline void __io_cq_unlock(struct io_ring_ctx *ctx)
597596
spin_unlock(&ctx->completion_lock);
598597
}
599598

599+
static inline void io_cq_lock(struct io_ring_ctx *ctx)
600+
__acquires(ctx->completion_lock)
601+
{
602+
spin_lock(&ctx->completion_lock);
603+
}
604+
605+
static inline void io_cq_unlock(struct io_ring_ctx *ctx)
606+
__releases(ctx->completion_lock)
607+
{
608+
spin_unlock(&ctx->completion_lock);
609+
}
610+
600611
/* keep it inlined for io_submit_flush_completions() */
601612
static inline void __io_cq_unlock_post(struct io_ring_ctx *ctx)
602613
__releases(ctx->completion_lock)
@@ -916,7 +927,7 @@ static void __io_req_complete_post(struct io_kiocb *req)
916927

917928
io_cq_lock(ctx);
918929
if (!(req->flags & REQ_F_CQE_SKIP))
919-
__io_fill_cqe_req(ctx, req);
930+
io_fill_cqe_req(ctx, req);
920931

921932
/*
922933
* If we're the last reference to this request, add to our locked
@@ -1074,9 +1085,9 @@ static void __io_req_find_next_prep(struct io_kiocb *req)
10741085
{
10751086
struct io_ring_ctx *ctx = req->ctx;
10761087

1077-
io_cq_lock(ctx);
1088+
spin_lock(&ctx->completion_lock);
10781089
io_disarm_next(req);
1079-
io_cq_unlock_post(ctx);
1090+
spin_unlock(&ctx->completion_lock);
10801091
}
10811092

10821093
static inline struct io_kiocb *io_req_find_next(struct io_kiocb *req)
@@ -2470,7 +2481,14 @@ static inline int io_cqring_wait_schedule(struct io_ring_ctx *ctx,
24702481
}
24712482
if (!schedule_hrtimeout(&timeout, HRTIMER_MODE_ABS))
24722483
return -ETIME;
2473-
return 1;
2484+
2485+
/*
2486+
* Run task_work after scheduling. If we got woken because of
2487+
* task_work being processed, run it now rather than let the caller
2488+
* do another wait loop.
2489+
*/
2490+
ret = io_run_task_work_sig(ctx);
2491+
return ret < 0 ? ret : 1;
24742492
}
24752493

24762494
/*
@@ -2535,6 +2553,8 @@ static int io_cqring_wait(struct io_ring_ctx *ctx, int min_events,
25352553
prepare_to_wait_exclusive(&ctx->cq_wait, &iowq.wq,
25362554
TASK_INTERRUPTIBLE);
25372555
ret = io_cqring_wait_schedule(ctx, &iowq, timeout);
2556+
if (__io_cqring_events_user(ctx) >= min_events)
2557+
break;
25382558
cond_resched();
25392559
} while (ret > 0);
25402560

io_uring/io_uring.h

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -87,17 +87,6 @@ static inline void io_req_task_work_add(struct io_kiocb *req)
8787
#define io_for_each_link(pos, head) \
8888
for (pos = (head); pos; pos = pos->link)
8989

90-
static inline void io_cq_lock(struct io_ring_ctx *ctx)
91-
__acquires(ctx->completion_lock)
92-
{
93-
spin_lock(&ctx->completion_lock);
94-
}
95-
96-
static inline void io_cq_unlock(struct io_ring_ctx *ctx)
97-
{
98-
spin_unlock(&ctx->completion_lock);
99-
}
100-
10190
void io_cq_unlock_post(struct io_ring_ctx *ctx);
10291

10392
static inline struct io_uring_cqe *io_get_cqe_overflow(struct io_ring_ctx *ctx,
@@ -277,8 +266,7 @@ static inline int io_run_task_work(void)
277266

278267
static inline bool io_task_work_pending(struct io_ring_ctx *ctx)
279268
{
280-
return test_thread_flag(TIF_NOTIFY_SIGNAL) ||
281-
!wq_list_empty(&ctx->work_llist);
269+
return task_work_pending(current) || !wq_list_empty(&ctx->work_llist);
282270
}
283271

284272
static inline int io_run_task_work_ctx(struct io_ring_ctx *ctx)

io_uring/net.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,7 @@ static int __io_compat_recvmsg_copy_hdr(struct io_kiocb *req,
494494
if (req->flags & REQ_F_BUFFER_SELECT) {
495495
compat_ssize_t clen;
496496

497+
iomsg->free_iov = NULL;
497498
if (msg.msg_iovlen == 0) {
498499
sr->len = 0;
499500
} else if (msg.msg_iovlen > 1) {
@@ -819,10 +820,10 @@ int io_recvmsg(struct io_kiocb *req, unsigned int issue_flags)
819820
goto retry_multishot;
820821

821822
if (mshot_finished) {
822-
io_netmsg_recycle(req, issue_flags);
823823
/* fast path, check for non-NULL to avoid function call */
824824
if (kmsg->free_iov)
825825
kfree(kmsg->free_iov);
826+
io_netmsg_recycle(req, issue_flags);
826827
req->flags &= ~REQ_F_NEED_CLEANUP;
827828
}
828829

io_uring/rw.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1062,7 +1062,7 @@ int io_do_iopoll(struct io_ring_ctx *ctx, bool force_nonspin)
10621062
continue;
10631063

10641064
req->cqe.flags = io_put_kbuf(req, 0);
1065-
__io_fill_cqe_req(req->ctx, req);
1065+
io_fill_cqe_req(req->ctx, req);
10661066
}
10671067

10681068
if (unlikely(!nr_events))

io_uring/timeout.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ static inline void io_put_req(struct io_kiocb *req)
5050
}
5151

5252
static bool io_kill_timeout(struct io_kiocb *req, int status)
53-
__must_hold(&req->ctx->completion_lock)
5453
__must_hold(&req->ctx->timeout_lock)
5554
{
5655
struct io_timeout_data *io = req->async_data;
@@ -70,12 +69,13 @@ static bool io_kill_timeout(struct io_kiocb *req, int status)
7069
}
7170

7271
__cold void io_flush_timeouts(struct io_ring_ctx *ctx)
73-
__must_hold(&ctx->completion_lock)
7472
{
75-
u32 seq = ctx->cached_cq_tail - atomic_read(&ctx->cq_timeouts);
73+
u32 seq;
7674
struct io_timeout *timeout, *tmp;
7775

7876
spin_lock_irq(&ctx->timeout_lock);
77+
seq = ctx->cached_cq_tail - atomic_read(&ctx->cq_timeouts);
78+
7979
list_for_each_entry_safe(timeout, tmp, &ctx->timeout_list, list) {
8080
struct io_kiocb *req = cmd_to_io_kiocb(timeout);
8181
u32 events_needed, events_got;
@@ -622,7 +622,11 @@ __cold bool io_kill_timeouts(struct io_ring_ctx *ctx, struct task_struct *tsk,
622622
struct io_timeout *timeout, *tmp;
623623
int canceled = 0;
624624

625-
io_cq_lock(ctx);
625+
/*
626+
* completion_lock is needed for io_match_task(). Take it before
627+
* timeout_lockfirst to keep locking ordering.
628+
*/
629+
spin_lock(&ctx->completion_lock);
626630
spin_lock_irq(&ctx->timeout_lock);
627631
list_for_each_entry_safe(timeout, tmp, &ctx->timeout_list, list) {
628632
struct io_kiocb *req = cmd_to_io_kiocb(timeout);
@@ -632,6 +636,6 @@ __cold bool io_kill_timeouts(struct io_ring_ctx *ctx, struct task_struct *tsk,
632636
canceled++;
633637
}
634638
spin_unlock_irq(&ctx->timeout_lock);
635-
io_cq_unlock_post(ctx);
639+
spin_unlock(&ctx->completion_lock);
636640
return canceled != 0;
637641
}

0 commit comments

Comments
 (0)