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/waitid: have io_waitid_complete() remove wait queue entry

Both callers of this need the entry potentially removed, so shift the
removal into the completion side and kill it from the two callers.

While at it, add a helper for removing the wait_queue_entry based
on the passed in io_kiocb.

Signed-off-by: Jens Axboe <axboe@kernel.dk>

+20 -6
+20 -6
io_uring/waitid.c
··· 109 109 return ret; 110 110 } 111 111 112 + static void io_waitid_remove_wq(struct io_kiocb *req) 113 + { 114 + struct io_waitid *iw = io_kiocb_to_cmd(req, struct io_waitid); 115 + struct wait_queue_head *head; 116 + 117 + head = READ_ONCE(iw->head); 118 + if (head) { 119 + struct io_waitid_async *iwa = req->async_data; 120 + 121 + iw->head = NULL; 122 + spin_lock_irq(&head->lock); 123 + list_del_init(&iwa->wo.child_wait.entry); 124 + spin_unlock_irq(&head->lock); 125 + } 126 + } 127 + 112 128 static void io_waitid_complete(struct io_kiocb *req, int ret) 113 129 { 114 130 struct io_waitid *iw = io_kiocb_to_cmd(req, struct io_waitid); ··· 135 119 lockdep_assert_held(&req->ctx->uring_lock); 136 120 137 121 hlist_del_init(&req->hash_node); 122 + io_waitid_remove_wq(req); 138 123 139 124 ret = io_waitid_finish(req, ret); 140 125 if (ret < 0) ··· 146 129 static bool __io_waitid_cancel(struct io_kiocb *req) 147 130 { 148 131 struct io_waitid *iw = io_kiocb_to_cmd(req, struct io_waitid); 149 - struct io_waitid_async *iwa = req->async_data; 132 + 133 + lockdep_assert_held(&req->ctx->uring_lock); 150 134 151 135 /* 152 136 * Mark us canceled regardless of ownership. This will prevent a ··· 159 141 if (atomic_fetch_inc(&iw->refs) & IO_WAITID_REF_MASK) 160 142 return false; 161 143 162 - spin_lock_irq(&iw->head->lock); 163 - list_del_init(&iwa->wo.child_wait.entry); 164 - spin_unlock_irq(&iw->head->lock); 165 144 io_waitid_complete(req, -ECANCELED); 166 145 io_req_queue_tw_complete(req, -ECANCELED); 167 146 return true; ··· 224 209 io_waitid_drop_issue_ref(req); 225 210 return; 226 211 } 227 - 228 - remove_wait_queue(iw->head, &iwa->wo.child_wait); 212 + /* fall through to complete, will kill waitqueue */ 229 213 } 230 214 } 231 215