xref: /linux/io_uring/waitid.c (revision 0cd64345c4ba127d27fa07a133d108ea92d38361)
1f31ecf67SJens Axboe // SPDX-License-Identifier: GPL-2.0
2f31ecf67SJens Axboe /*
3f31ecf67SJens Axboe  * Support for async notification of waitid
4f31ecf67SJens Axboe  */
5f31ecf67SJens Axboe #include <linux/kernel.h>
6f31ecf67SJens Axboe #include <linux/errno.h>
7f31ecf67SJens Axboe #include <linux/fs.h>
8f31ecf67SJens Axboe #include <linux/file.h>
9f31ecf67SJens Axboe #include <linux/compat.h>
10f31ecf67SJens Axboe #include <linux/io_uring.h>
11f31ecf67SJens Axboe 
12f31ecf67SJens Axboe #include <uapi/linux/io_uring.h>
13f31ecf67SJens Axboe 
14f31ecf67SJens Axboe #include "io_uring.h"
15f31ecf67SJens Axboe #include "cancel.h"
16f31ecf67SJens Axboe #include "waitid.h"
17f31ecf67SJens Axboe #include "../kernel/exit.h"
18f31ecf67SJens Axboe 
19bcf8a029SCaleb Sander Mateos static void io_waitid_cb(struct io_kiocb *req, io_tw_token_t tw);
20f31ecf67SJens Axboe 
21f31ecf67SJens Axboe #define IO_WAITID_CANCEL_FLAG	BIT(31)
22f31ecf67SJens Axboe #define IO_WAITID_REF_MASK	GENMASK(30, 0)
23f31ecf67SJens Axboe 
24f31ecf67SJens Axboe struct io_waitid {
25f31ecf67SJens Axboe 	struct file *file;
26f31ecf67SJens Axboe 	int which;
27f31ecf67SJens Axboe 	pid_t upid;
28f31ecf67SJens Axboe 	int options;
29f31ecf67SJens Axboe 	atomic_t refs;
30f31ecf67SJens Axboe 	struct wait_queue_head *head;
31f31ecf67SJens Axboe 	struct siginfo __user *infop;
32f31ecf67SJens Axboe 	struct waitid_info info;
33f31ecf67SJens Axboe };
34f31ecf67SJens Axboe 
35f31ecf67SJens Axboe static void io_waitid_free(struct io_kiocb *req)
36f31ecf67SJens Axboe {
37f31ecf67SJens Axboe 	struct io_waitid_async *iwa = req->async_data;
38f31ecf67SJens Axboe 
39f31ecf67SJens Axboe 	put_pid(iwa->wo.wo_pid);
40f31ecf67SJens Axboe 	kfree(req->async_data);
41f31ecf67SJens Axboe 	req->async_data = NULL;
42f31ecf67SJens Axboe 	req->flags &= ~REQ_F_ASYNC_DATA;
43f31ecf67SJens Axboe }
44f31ecf67SJens Axboe 
45f31ecf67SJens Axboe static bool io_waitid_compat_copy_si(struct io_waitid *iw, int signo)
46f31ecf67SJens Axboe {
47f31ecf67SJens Axboe 	struct compat_siginfo __user *infop;
48f31ecf67SJens Axboe 	bool ret;
49f31ecf67SJens Axboe 
50f31ecf67SJens Axboe 	infop = (struct compat_siginfo __user *) iw->infop;
51f31ecf67SJens Axboe 
52f31ecf67SJens Axboe 	if (!user_write_access_begin(infop, sizeof(*infop)))
53f31ecf67SJens Axboe 		return false;
54f31ecf67SJens Axboe 
55f31ecf67SJens Axboe 	unsafe_put_user(signo, &infop->si_signo, Efault);
56f31ecf67SJens Axboe 	unsafe_put_user(0, &infop->si_errno, Efault);
57f31ecf67SJens Axboe 	unsafe_put_user(iw->info.cause, &infop->si_code, Efault);
58f31ecf67SJens Axboe 	unsafe_put_user(iw->info.pid, &infop->si_pid, Efault);
59f31ecf67SJens Axboe 	unsafe_put_user(iw->info.uid, &infop->si_uid, Efault);
60f31ecf67SJens Axboe 	unsafe_put_user(iw->info.status, &infop->si_status, Efault);
61f31ecf67SJens Axboe 	ret = true;
62f31ecf67SJens Axboe done:
63f31ecf67SJens Axboe 	user_write_access_end();
64f31ecf67SJens Axboe 	return ret;
65f31ecf67SJens Axboe Efault:
66f31ecf67SJens Axboe 	ret = false;
67f31ecf67SJens Axboe 	goto done;
68f31ecf67SJens Axboe }
69f31ecf67SJens Axboe 
70f31ecf67SJens Axboe static bool io_waitid_copy_si(struct io_kiocb *req, int signo)
71f31ecf67SJens Axboe {
72f31ecf67SJens Axboe 	struct io_waitid *iw = io_kiocb_to_cmd(req, struct io_waitid);
73f31ecf67SJens Axboe 	bool ret;
74f31ecf67SJens Axboe 
75f31ecf67SJens Axboe 	if (!iw->infop)
76f31ecf67SJens Axboe 		return true;
77f31ecf67SJens Axboe 
78*0cd64345SPavel Begunkov 	if (io_is_compat(req->ctx))
79f31ecf67SJens Axboe 		return io_waitid_compat_copy_si(iw, signo);
80f31ecf67SJens Axboe 
81f31ecf67SJens Axboe 	if (!user_write_access_begin(iw->infop, sizeof(*iw->infop)))
82f31ecf67SJens Axboe 		return false;
83f31ecf67SJens Axboe 
84f31ecf67SJens Axboe 	unsafe_put_user(signo, &iw->infop->si_signo, Efault);
85f31ecf67SJens Axboe 	unsafe_put_user(0, &iw->infop->si_errno, Efault);
86f31ecf67SJens Axboe 	unsafe_put_user(iw->info.cause, &iw->infop->si_code, Efault);
87f31ecf67SJens Axboe 	unsafe_put_user(iw->info.pid, &iw->infop->si_pid, Efault);
88f31ecf67SJens Axboe 	unsafe_put_user(iw->info.uid, &iw->infop->si_uid, Efault);
89f31ecf67SJens Axboe 	unsafe_put_user(iw->info.status, &iw->infop->si_status, Efault);
90f31ecf67SJens Axboe 	ret = true;
91f31ecf67SJens Axboe done:
92f31ecf67SJens Axboe 	user_write_access_end();
93f31ecf67SJens Axboe 	return ret;
94f31ecf67SJens Axboe Efault:
95f31ecf67SJens Axboe 	ret = false;
96f31ecf67SJens Axboe 	goto done;
97f31ecf67SJens Axboe }
98f31ecf67SJens Axboe 
99f31ecf67SJens Axboe static int io_waitid_finish(struct io_kiocb *req, int ret)
100f31ecf67SJens Axboe {
101f31ecf67SJens Axboe 	int signo = 0;
102f31ecf67SJens Axboe 
103f31ecf67SJens Axboe 	if (ret > 0) {
104f31ecf67SJens Axboe 		signo = SIGCHLD;
105f31ecf67SJens Axboe 		ret = 0;
106f31ecf67SJens Axboe 	}
107f31ecf67SJens Axboe 
108f31ecf67SJens Axboe 	if (!io_waitid_copy_si(req, signo))
109f31ecf67SJens Axboe 		ret = -EFAULT;
110f31ecf67SJens Axboe 	io_waitid_free(req);
111f31ecf67SJens Axboe 	return ret;
112f31ecf67SJens Axboe }
113f31ecf67SJens Axboe 
114f31ecf67SJens Axboe static void io_waitid_complete(struct io_kiocb *req, int ret)
115f31ecf67SJens Axboe {
116f31ecf67SJens Axboe 	struct io_waitid *iw = io_kiocb_to_cmd(req, struct io_waitid);
117f31ecf67SJens Axboe 
118f31ecf67SJens Axboe 	/* anyone completing better be holding a reference */
119f31ecf67SJens Axboe 	WARN_ON_ONCE(!(atomic_read(&iw->refs) & IO_WAITID_REF_MASK));
120f31ecf67SJens Axboe 
121f31ecf67SJens Axboe 	lockdep_assert_held(&req->ctx->uring_lock);
122f31ecf67SJens Axboe 
123f31ecf67SJens Axboe 	hlist_del_init(&req->hash_node);
124f31ecf67SJens Axboe 
125f31ecf67SJens Axboe 	ret = io_waitid_finish(req, ret);
126f31ecf67SJens Axboe 	if (ret < 0)
127f31ecf67SJens Axboe 		req_set_fail(req);
128f31ecf67SJens Axboe 	io_req_set_res(req, ret, 0);
129f31ecf67SJens Axboe }
130f31ecf67SJens Axboe 
1317d9944f5SJens Axboe static bool __io_waitid_cancel(struct io_kiocb *req)
132f31ecf67SJens Axboe {
133f31ecf67SJens Axboe 	struct io_waitid *iw = io_kiocb_to_cmd(req, struct io_waitid);
134f31ecf67SJens Axboe 	struct io_waitid_async *iwa = req->async_data;
135f31ecf67SJens Axboe 
136f31ecf67SJens Axboe 	/*
137f31ecf67SJens Axboe 	 * Mark us canceled regardless of ownership. This will prevent a
138f31ecf67SJens Axboe 	 * potential retry from a spurious wakeup.
139f31ecf67SJens Axboe 	 */
140f31ecf67SJens Axboe 	atomic_or(IO_WAITID_CANCEL_FLAG, &iw->refs);
141f31ecf67SJens Axboe 
142f31ecf67SJens Axboe 	/* claim ownership */
143f31ecf67SJens Axboe 	if (atomic_fetch_inc(&iw->refs) & IO_WAITID_REF_MASK)
144f31ecf67SJens Axboe 		return false;
145f31ecf67SJens Axboe 
146f31ecf67SJens Axboe 	spin_lock_irq(&iw->head->lock);
147f31ecf67SJens Axboe 	list_del_init(&iwa->wo.child_wait.entry);
148f31ecf67SJens Axboe 	spin_unlock_irq(&iw->head->lock);
149f31ecf67SJens Axboe 	io_waitid_complete(req, -ECANCELED);
15006521ac0SPavel Begunkov 	io_req_queue_tw_complete(req, -ECANCELED);
151f31ecf67SJens Axboe 	return true;
152f31ecf67SJens Axboe }
153f31ecf67SJens Axboe 
154f31ecf67SJens Axboe int io_waitid_cancel(struct io_ring_ctx *ctx, struct io_cancel_data *cd,
155f31ecf67SJens Axboe 		     unsigned int issue_flags)
156f31ecf67SJens Axboe {
157932de5e3SJens Axboe 	return io_cancel_remove(ctx, cd, issue_flags, &ctx->waitid_list, __io_waitid_cancel);
158f31ecf67SJens Axboe }
159f31ecf67SJens Axboe 
160f03baeceSJens Axboe bool io_waitid_remove_all(struct io_ring_ctx *ctx, struct io_uring_task *tctx,
161f31ecf67SJens Axboe 			  bool cancel_all)
162f31ecf67SJens Axboe {
1637d9944f5SJens Axboe 	return io_cancel_remove_all(ctx, tctx, &ctx->waitid_list, cancel_all, __io_waitid_cancel);
164f31ecf67SJens Axboe }
165f31ecf67SJens Axboe 
166f31ecf67SJens Axboe static inline bool io_waitid_drop_issue_ref(struct io_kiocb *req)
167f31ecf67SJens Axboe {
168f31ecf67SJens Axboe 	struct io_waitid *iw = io_kiocb_to_cmd(req, struct io_waitid);
169f31ecf67SJens Axboe 	struct io_waitid_async *iwa = req->async_data;
170f31ecf67SJens Axboe 
171f31ecf67SJens Axboe 	if (!atomic_sub_return(1, &iw->refs))
172f31ecf67SJens Axboe 		return false;
173f31ecf67SJens Axboe 
174f31ecf67SJens Axboe 	/*
175f31ecf67SJens Axboe 	 * Wakeup triggered, racing with us. It was prevented from
176f31ecf67SJens Axboe 	 * completing because of that, queue up the tw to do that.
177f31ecf67SJens Axboe 	 */
178f31ecf67SJens Axboe 	req->io_task_work.func = io_waitid_cb;
179f31ecf67SJens Axboe 	io_req_task_work_add(req);
180f31ecf67SJens Axboe 	remove_wait_queue(iw->head, &iwa->wo.child_wait);
181f31ecf67SJens Axboe 	return true;
182f31ecf67SJens Axboe }
183f31ecf67SJens Axboe 
184bcf8a029SCaleb Sander Mateos static void io_waitid_cb(struct io_kiocb *req, io_tw_token_t tw)
185f31ecf67SJens Axboe {
186f31ecf67SJens Axboe 	struct io_waitid_async *iwa = req->async_data;
187f31ecf67SJens Axboe 	struct io_ring_ctx *ctx = req->ctx;
188f31ecf67SJens Axboe 	int ret;
189f31ecf67SJens Axboe 
190bcf8a029SCaleb Sander Mateos 	io_tw_lock(ctx, tw);
191f31ecf67SJens Axboe 
192f31ecf67SJens Axboe 	ret = __do_wait(&iwa->wo);
193f31ecf67SJens Axboe 
194f31ecf67SJens Axboe 	/*
195f31ecf67SJens Axboe 	 * If we get -ERESTARTSYS here, we need to re-arm and check again
196f31ecf67SJens Axboe 	 * to ensure we get another callback. If the retry works, then we can
197f31ecf67SJens Axboe 	 * just remove ourselves from the waitqueue again and finish the
198f31ecf67SJens Axboe 	 * request.
199f31ecf67SJens Axboe 	 */
200f31ecf67SJens Axboe 	if (unlikely(ret == -ERESTARTSYS)) {
201f31ecf67SJens Axboe 		struct io_waitid *iw = io_kiocb_to_cmd(req, struct io_waitid);
202f31ecf67SJens Axboe 
203f31ecf67SJens Axboe 		/* Don't retry if cancel found it meanwhile */
204f31ecf67SJens Axboe 		ret = -ECANCELED;
205f31ecf67SJens Axboe 		if (!(atomic_read(&iw->refs) & IO_WAITID_CANCEL_FLAG)) {
206f31ecf67SJens Axboe 			iw->head = &current->signal->wait_chldexit;
207f31ecf67SJens Axboe 			add_wait_queue(iw->head, &iwa->wo.child_wait);
208f31ecf67SJens Axboe 			ret = __do_wait(&iwa->wo);
209f31ecf67SJens Axboe 			if (ret == -ERESTARTSYS) {
210f31ecf67SJens Axboe 				/* retry armed, drop our ref */
211f31ecf67SJens Axboe 				io_waitid_drop_issue_ref(req);
212f31ecf67SJens Axboe 				return;
213f31ecf67SJens Axboe 			}
214f31ecf67SJens Axboe 
215f31ecf67SJens Axboe 			remove_wait_queue(iw->head, &iwa->wo.child_wait);
216f31ecf67SJens Axboe 		}
217f31ecf67SJens Axboe 	}
218f31ecf67SJens Axboe 
219f31ecf67SJens Axboe 	io_waitid_complete(req, ret);
220bcf8a029SCaleb Sander Mateos 	io_req_task_complete(req, tw);
221f31ecf67SJens Axboe }
222f31ecf67SJens Axboe 
223f31ecf67SJens Axboe static int io_waitid_wait(struct wait_queue_entry *wait, unsigned mode,
224f31ecf67SJens Axboe 			  int sync, void *key)
225f31ecf67SJens Axboe {
226f31ecf67SJens Axboe 	struct wait_opts *wo = container_of(wait, struct wait_opts, child_wait);
227f31ecf67SJens Axboe 	struct io_waitid_async *iwa = container_of(wo, struct io_waitid_async, wo);
228f31ecf67SJens Axboe 	struct io_kiocb *req = iwa->req;
229f31ecf67SJens Axboe 	struct io_waitid *iw = io_kiocb_to_cmd(req, struct io_waitid);
230f31ecf67SJens Axboe 	struct task_struct *p = key;
231f31ecf67SJens Axboe 
232f31ecf67SJens Axboe 	if (!pid_child_should_wake(wo, p))
233f31ecf67SJens Axboe 		return 0;
234f31ecf67SJens Axboe 
235f31ecf67SJens Axboe 	/* cancel is in progress */
236f31ecf67SJens Axboe 	if (atomic_fetch_inc(&iw->refs) & IO_WAITID_REF_MASK)
237f31ecf67SJens Axboe 		return 1;
238f31ecf67SJens Axboe 
239f31ecf67SJens Axboe 	req->io_task_work.func = io_waitid_cb;
240f31ecf67SJens Axboe 	io_req_task_work_add(req);
241f31ecf67SJens Axboe 	list_del_init(&wait->entry);
242f31ecf67SJens Axboe 	return 1;
243f31ecf67SJens Axboe }
244f31ecf67SJens Axboe 
245f31ecf67SJens Axboe int io_waitid_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
246f31ecf67SJens Axboe {
247f31ecf67SJens Axboe 	struct io_waitid *iw = io_kiocb_to_cmd(req, struct io_waitid);
2482b4fc4cdSJens Axboe 	struct io_waitid_async *iwa;
249f31ecf67SJens Axboe 
250f31ecf67SJens Axboe 	if (sqe->addr || sqe->buf_index || sqe->addr3 || sqe->waitid_flags)
251f31ecf67SJens Axboe 		return -EINVAL;
252f31ecf67SJens Axboe 
2532b4fc4cdSJens Axboe 	iwa = io_uring_alloc_async_data(NULL, req);
2542b4fc4cdSJens Axboe 	if (!unlikely(iwa))
2552b4fc4cdSJens Axboe 		return -ENOMEM;
2562b4fc4cdSJens Axboe 	iwa->req = req;
2572b4fc4cdSJens Axboe 
258f31ecf67SJens Axboe 	iw->which = READ_ONCE(sqe->len);
259f31ecf67SJens Axboe 	iw->upid = READ_ONCE(sqe->fd);
260f31ecf67SJens Axboe 	iw->options = READ_ONCE(sqe->file_index);
261f31ecf67SJens Axboe 	iw->infop = u64_to_user_ptr(READ_ONCE(sqe->addr2));
262f31ecf67SJens Axboe 	return 0;
263f31ecf67SJens Axboe }
264f31ecf67SJens Axboe 
265f31ecf67SJens Axboe int io_waitid(struct io_kiocb *req, unsigned int issue_flags)
266f31ecf67SJens Axboe {
267f31ecf67SJens Axboe 	struct io_waitid *iw = io_kiocb_to_cmd(req, struct io_waitid);
2682b4fc4cdSJens Axboe 	struct io_waitid_async *iwa = req->async_data;
269f31ecf67SJens Axboe 	struct io_ring_ctx *ctx = req->ctx;
270f31ecf67SJens Axboe 	int ret;
271f31ecf67SJens Axboe 
272f31ecf67SJens Axboe 	ret = kernel_waitid_prepare(&iwa->wo, iw->which, iw->upid, &iw->info,
273f31ecf67SJens Axboe 					iw->options, NULL);
274f31ecf67SJens Axboe 	if (ret)
275f31ecf67SJens Axboe 		goto done;
276f31ecf67SJens Axboe 
277f31ecf67SJens Axboe 	/*
278f31ecf67SJens Axboe 	 * Mark the request as busy upfront, in case we're racing with the
279f31ecf67SJens Axboe 	 * wakeup. If we are, then we'll notice when we drop this initial
280f31ecf67SJens Axboe 	 * reference again after arming.
281f31ecf67SJens Axboe 	 */
282f31ecf67SJens Axboe 	atomic_set(&iw->refs, 1);
283f31ecf67SJens Axboe 
284f31ecf67SJens Axboe 	/*
285f31ecf67SJens Axboe 	 * Cancel must hold the ctx lock, so there's no risk of cancelation
286f31ecf67SJens Axboe 	 * finding us until a) we remain on the list, and b) the lock is
287f31ecf67SJens Axboe 	 * dropped. We only need to worry about racing with the wakeup
288f31ecf67SJens Axboe 	 * callback.
289f31ecf67SJens Axboe 	 */
290f31ecf67SJens Axboe 	io_ring_submit_lock(ctx, issue_flags);
291f31ecf67SJens Axboe 	hlist_add_head(&req->hash_node, &ctx->waitid_list);
292f31ecf67SJens Axboe 
293f31ecf67SJens Axboe 	init_waitqueue_func_entry(&iwa->wo.child_wait, io_waitid_wait);
294b6f58a3fSJens Axboe 	iwa->wo.child_wait.private = req->tctx->task;
295f31ecf67SJens Axboe 	iw->head = &current->signal->wait_chldexit;
296f31ecf67SJens Axboe 	add_wait_queue(iw->head, &iwa->wo.child_wait);
297f31ecf67SJens Axboe 
298f31ecf67SJens Axboe 	ret = __do_wait(&iwa->wo);
299f31ecf67SJens Axboe 	if (ret == -ERESTARTSYS) {
300f31ecf67SJens Axboe 		/*
301f31ecf67SJens Axboe 		 * Nobody else grabbed a reference, it'll complete when we get
302f31ecf67SJens Axboe 		 * a waitqueue callback, or if someone cancels it.
303f31ecf67SJens Axboe 		 */
304f31ecf67SJens Axboe 		if (!io_waitid_drop_issue_ref(req)) {
305f31ecf67SJens Axboe 			io_ring_submit_unlock(ctx, issue_flags);
306f31ecf67SJens Axboe 			return IOU_ISSUE_SKIP_COMPLETE;
307f31ecf67SJens Axboe 		}
308f31ecf67SJens Axboe 
309f31ecf67SJens Axboe 		/*
310f31ecf67SJens Axboe 		 * Wakeup triggered, racing with us. It was prevented from
311f31ecf67SJens Axboe 		 * completing because of that, queue up the tw to do that.
312f31ecf67SJens Axboe 		 */
313f31ecf67SJens Axboe 		io_ring_submit_unlock(ctx, issue_flags);
314f31ecf67SJens Axboe 		return IOU_ISSUE_SKIP_COMPLETE;
315f31ecf67SJens Axboe 	}
316f31ecf67SJens Axboe 
317f31ecf67SJens Axboe 	hlist_del_init(&req->hash_node);
318f31ecf67SJens Axboe 	remove_wait_queue(iw->head, &iwa->wo.child_wait);
319f31ecf67SJens Axboe 	ret = io_waitid_finish(req, ret);
320f31ecf67SJens Axboe 
321f31ecf67SJens Axboe 	io_ring_submit_unlock(ctx, issue_flags);
322f31ecf67SJens Axboe done:
323f31ecf67SJens Axboe 	if (ret < 0)
324f31ecf67SJens Axboe 		req_set_fail(req);
325f31ecf67SJens Axboe 	io_req_set_res(req, ret, 0);
326f31ecf67SJens Axboe 	return IOU_OK;
327f31ecf67SJens Axboe }
328