Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

io_uring/eventfd: clean up rcu locking

Conditional locking is never welcome if there are better options. Move
rcu locking into io_eventfd_signal(), make it unconditional and use
guards. It also helps with sparse warnings.

Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
Link: https://lore.kernel.org/r/91a925e708ca8a5aa7fee61f96d29b24ea9adeaf.1745493845.git.asml.silence@gmail.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>

authored by

Pavel Begunkov and committed by
Jens Axboe
da01f60f 62f666df

+7 -17
+7 -17
io_uring/eventfd.c
··· 47 47 io_eventfd_put(ev_fd); 48 48 } 49 49 50 - static void io_eventfd_release(struct io_ev_fd *ev_fd, bool put_ref) 51 - { 52 - if (put_ref) 53 - io_eventfd_put(ev_fd); 54 - rcu_read_unlock(); 55 - } 56 - 57 50 /* 58 51 * Returns true if the caller should put the ev_fd reference, false if not. 59 52 */ ··· 82 89 { 83 90 struct io_ev_fd *ev_fd; 84 91 85 - if (READ_ONCE(ctx->rings->cq_flags) & IORING_CQ_EVENTFD_DISABLED) 86 - return NULL; 87 - 88 - rcu_read_lock(); 89 - 90 92 /* 91 93 * rcu_dereference ctx->io_ev_fd once and use it for both for checking 92 94 * and eventfd_signal ··· 96 108 if (io_eventfd_trigger(ev_fd) && refcount_inc_not_zero(&ev_fd->refs)) 97 109 return ev_fd; 98 110 99 - rcu_read_unlock(); 100 111 return NULL; 101 112 } 102 113 103 114 void io_eventfd_signal(struct io_ring_ctx *ctx, bool cqe_event) 104 115 { 105 - bool skip = false, put_ref = true; 116 + bool skip = false; 106 117 struct io_ev_fd *ev_fd; 107 118 119 + if (READ_ONCE(ctx->rings->cq_flags) & IORING_CQ_EVENTFD_DISABLED) 120 + return; 121 + 122 + guard(rcu)(); 108 123 ev_fd = io_eventfd_grab(ctx); 109 124 if (!ev_fd) 110 125 return; ··· 128 137 spin_unlock(&ctx->completion_lock); 129 138 } 130 139 131 - if (!skip) 132 - put_ref = __io_eventfd_signal(ev_fd); 133 - io_eventfd_release(ev_fd, put_ref); 140 + if (skip || __io_eventfd_signal(ev_fd)) 141 + io_eventfd_put(ev_fd); 134 142 } 135 143 136 144 int io_eventfd_register(struct io_ring_ctx *ctx, void __user *arg,