IO-Uring Archive on lore.kernel.org
 help / color / Atom feed
* [PATCH 0/3] iopoll fixes
@ 2020-06-24 16:50 Pavel Begunkov
  2020-06-24 16:50 ` [PATCH 1/3] io_uring: fix hanging iopoll in case of -EAGAIN Pavel Begunkov
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: Pavel Begunkov @ 2020-06-24 16:50 UTC (permalink / raw)
  To: Jens Axboe, io-uring, linux-kernel

Did more comprehensive iopoll testing and found some more problems.

[1] is from the previous series. Actually, v2 for this one, addressing
the double-reissue bug found by Jens. It maybe not as efficient, but
simple and easy to backport.

[2,3] current->mm NULL deref

Pavel Begunkov (3):
  io_uring: fix hanging iopoll in case of -EAGAIN
  io_uring: fix current->mm NULL dereference on exit
  io_uring: fix NULL-mm for linked reqs

 fs/io_uring.c | 33 ++++++++++++++++++++++-----------
 1 file changed, 22 insertions(+), 11 deletions(-)

-- 
2.24.0


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/3] io_uring: fix hanging iopoll in case of -EAGAIN
  2020-06-24 16:50 [PATCH 0/3] iopoll fixes Pavel Begunkov
@ 2020-06-24 16:50 ` Pavel Begunkov
  2020-06-24 16:50 ` [PATCH 2/3] io_uring: fix current->mm NULL dereference on exit Pavel Begunkov
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 6+ messages in thread
From: Pavel Begunkov @ 2020-06-24 16:50 UTC (permalink / raw)
  To: Jens Axboe, io-uring, linux-kernel

io_do_iopoll() won't do anything with a request unless
req->iopoll_completed is set. So io_complete_rw_iopoll() has to set
it, otherwise io_do_iopoll() will poll a file again and again even
though the request of interest was completed long time ago.

Also, remove -EAGAIN check from io_issue_sqe() as it races with
the changed lines. The request will take the long way and be
resubmitted from io_iopoll*().

Fixes: bbde017a32b3 ("io_uring: add memory barrier to synchronize
io_kiocb's result and iopoll_completed")
Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
---
 fs/io_uring.c | 9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/fs/io_uring.c b/fs/io_uring.c
index c686061c3762..fb88a537f471 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -2104,10 +2104,8 @@ static void io_complete_rw_iopoll(struct kiocb *kiocb, long res, long res2)
 
 	WRITE_ONCE(req->result, res);
 	/* order with io_poll_complete() checking ->result */
-	if (res != -EAGAIN) {
-		smp_wmb();
-		WRITE_ONCE(req->iopoll_completed, 1);
-	}
+	smp_wmb();
+	WRITE_ONCE(req->iopoll_completed, 1);
 }
 
 /*
@@ -5592,9 +5590,6 @@ static int io_issue_sqe(struct io_kiocb *req, const struct io_uring_sqe *sqe,
 	if ((ctx->flags & IORING_SETUP_IOPOLL) && req->file) {
 		const bool in_async = io_wq_current_is_worker();
 
-		if (req->result == -EAGAIN)
-			return -EAGAIN;
-
 		/* workqueue context doesn't hold uring_lock, grab it now */
 		if (in_async)
 			mutex_lock(&ctx->uring_lock);
-- 
2.24.0


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 2/3] io_uring: fix current->mm NULL dereference on exit
  2020-06-24 16:50 [PATCH 0/3] iopoll fixes Pavel Begunkov
  2020-06-24 16:50 ` [PATCH 1/3] io_uring: fix hanging iopoll in case of -EAGAIN Pavel Begunkov
@ 2020-06-24 16:50 ` Pavel Begunkov
  2020-06-24 16:50 ` [PATCH 3/3] io_uring: fix NULL-mm for linked reqs Pavel Begunkov
  2020-06-24 17:03 ` [PATCH 0/3] iopoll fixes Pavel Begunkov
  3 siblings, 0 replies; 6+ messages in thread
From: Pavel Begunkov @ 2020-06-24 16:50 UTC (permalink / raw)
  To: Jens Axboe, io-uring, linux-kernel

Don't reissue requests from io_iopoll_reap_events(), the task may not
have mm, which ends up with NULL. It's better to kill everything off on
exit anyway.

[  677.734670] RIP: 0010:io_iopoll_complete+0x27e/0x630
...
[  677.734679] Call Trace:
[  677.734695]  ? __send_signal+0x1f2/0x420
[  677.734698]  ? _raw_spin_unlock_irqrestore+0x24/0x40
[  677.734699]  ? send_signal+0xf5/0x140
[  677.734700]  io_iopoll_getevents+0x12f/0x1a0
[  677.734702]  io_iopoll_reap_events.part.0+0x5e/0xa0
[  677.734703]  io_ring_ctx_wait_and_kill+0x132/0x1c0
[  677.734704]  io_uring_release+0x20/0x30
[  677.734706]  __fput+0xcd/0x230
[  677.734707]  ____fput+0xe/0x10
[  677.734709]  task_work_run+0x67/0xa0
[  677.734710]  do_exit+0x35d/0xb70
[  677.734712]  do_group_exit+0x43/0xa0
[  677.734713]  get_signal+0x140/0x900
[  677.734715]  do_signal+0x37/0x780
[  677.734717]  ? enqueue_hrtimer+0x41/0xb0
[  677.734718]  ? recalibrate_cpu_khz+0x10/0x10
[  677.734720]  ? ktime_get+0x3e/0xa0
[  677.734721]  ? lapic_next_deadline+0x26/0x30
[  677.734723]  ? tick_program_event+0x4d/0x90
[  677.734724]  ? __hrtimer_get_next_event+0x4d/0x80
[  677.734726]  __prepare_exit_to_usermode+0x126/0x1c0
[  677.734741]  prepare_exit_to_usermode+0x9/0x40
[  677.734742]  idtentry_exit_cond_rcu+0x4c/0x60
[  677.734743]  sysvec_reschedule_ipi+0x92/0x160
[  677.734744]  ? asm_sysvec_reschedule_ipi+0xa/0x20
[  677.734745]  asm_sysvec_reschedule_ipi+0x12/0x20

Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
---
 fs/io_uring.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/fs/io_uring.c b/fs/io_uring.c
index fb88a537f471..578ec2e39712 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -884,6 +884,7 @@ enum io_mem_account {
 	ACCT_PINNED,
 };
 
+static void io_complete_rw_common(struct kiocb *kiocb, long res);
 static void io_wq_submit_work(struct io_wq_work **workptr);
 static void io_cqring_fill_event(struct io_kiocb *req, long res);
 static void io_put_req(struct io_kiocb *req);
@@ -1756,6 +1757,14 @@ static void io_iopoll_queue(struct list_head *again)
 	do {
 		req = list_first_entry(again, struct io_kiocb, list);
 		list_del(&req->list);
+
+		/* shouldn't happen unless io_uring is dying, cancel reqs */
+		if (unlikely(!current->mm)) {
+			io_complete_rw_common(&req->rw.kiocb, -EAGAIN);
+			io_put_req(req);
+			continue;
+		}
+
 		refcount_inc(&req->refs);
 		io_queue_async_work(req);
 	} while (!list_empty(again));
-- 
2.24.0


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 3/3] io_uring: fix NULL-mm for linked reqs
  2020-06-24 16:50 [PATCH 0/3] iopoll fixes Pavel Begunkov
  2020-06-24 16:50 ` [PATCH 1/3] io_uring: fix hanging iopoll in case of -EAGAIN Pavel Begunkov
  2020-06-24 16:50 ` [PATCH 2/3] io_uring: fix current->mm NULL dereference on exit Pavel Begunkov
@ 2020-06-24 16:50 ` Pavel Begunkov
  2020-06-24 17:03 ` [PATCH 0/3] iopoll fixes Pavel Begunkov
  3 siblings, 0 replies; 6+ messages in thread
From: Pavel Begunkov @ 2020-06-24 16:50 UTC (permalink / raw)
  To: Jens Axboe, io-uring, linux-kernel

__io_queue_sqe() tries to handle all request of a link,
so it's not enough to grab mm in io_sq_thread_acquire_mm()
based just on the head.

Don't check req->needs_mm and do it always.

Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
---
 fs/io_uring.c | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/fs/io_uring.c b/fs/io_uring.c
index 578ec2e39712..df0dba607966 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -2000,10 +2000,9 @@ static void io_sq_thread_drop_mm(struct io_ring_ctx *ctx)
 	}
 }
 
-static int io_sq_thread_acquire_mm(struct io_ring_ctx *ctx,
-				   struct io_kiocb *req)
+static int __io_sq_thread_acquire_mm(struct io_ring_ctx *ctx)
 {
-	if (io_op_defs[req->opcode].needs_mm && !current->mm) {
+	if (!current->mm) {
 		if (unlikely(!mmget_not_zero(ctx->sqo_mm)))
 			return -EFAULT;
 		kthread_use_mm(ctx->sqo_mm);
@@ -2012,6 +2011,14 @@ static int io_sq_thread_acquire_mm(struct io_ring_ctx *ctx,
 	return 0;
 }
 
+static int io_sq_thread_acquire_mm(struct io_ring_ctx *ctx,
+				   struct io_kiocb *req)
+{
+	if (!io_op_defs[req->opcode].needs_mm)
+		return 0;
+	return __io_sq_thread_acquire_mm(ctx);
+}
+
 #ifdef CONFIG_BLOCK
 static bool io_resubmit_prep(struct io_kiocb *req, int error)
 {
@@ -2788,7 +2795,7 @@ static void io_async_buf_retry(struct callback_head *cb)
 	ctx = req->ctx;
 
 	__set_current_state(TASK_RUNNING);
-	if (!io_sq_thread_acquire_mm(ctx, req)) {
+	if (!__io_sq_thread_acquire_mm(ctx)) {
 		mutex_lock(&ctx->uring_lock);
 		__io_queue_sqe(req, NULL);
 		mutex_unlock(&ctx->uring_lock);
-- 
2.24.0


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 0/3] iopoll fixes
  2020-06-24 16:50 [PATCH 0/3] iopoll fixes Pavel Begunkov
                   ` (2 preceding siblings ...)
  2020-06-24 16:50 ` [PATCH 3/3] io_uring: fix NULL-mm for linked reqs Pavel Begunkov
@ 2020-06-24 17:03 ` Pavel Begunkov
  2020-06-24 19:46   ` Jens Axboe
  3 siblings, 1 reply; 6+ messages in thread
From: Pavel Begunkov @ 2020-06-24 17:03 UTC (permalink / raw)
  To: Jens Axboe, io-uring, linux-kernel

On 24/06/2020 19:50, Pavel Begunkov wrote:
> Did more comprehensive iopoll testing and found some more problems.
> 
> [1] is from the previous series. Actually, v2 for this one, addressing
> the double-reissue bug found by Jens. It maybe not as efficient, but
> simple and easy to backport.
> 
> [2,3] current->mm NULL deref

And yet there are issues left... I'll resend

> 
> Pavel Begunkov (3):
>   io_uring: fix hanging iopoll in case of -EAGAIN
>   io_uring: fix current->mm NULL dereference on exit
>   io_uring: fix NULL-mm for linked reqs
> 
>  fs/io_uring.c | 33 ++++++++++++++++++++++-----------
>  1 file changed, 22 insertions(+), 11 deletions(-)
> 

-- 
Pavel Begunkov

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 0/3] iopoll fixes
  2020-06-24 17:03 ` [PATCH 0/3] iopoll fixes Pavel Begunkov
@ 2020-06-24 19:46   ` Jens Axboe
  0 siblings, 0 replies; 6+ messages in thread
From: Jens Axboe @ 2020-06-24 19:46 UTC (permalink / raw)
  To: Pavel Begunkov, io-uring, linux-kernel

On 6/24/20 11:03 AM, Pavel Begunkov wrote:
> On 24/06/2020 19:50, Pavel Begunkov wrote:
>> Did more comprehensive iopoll testing and found some more problems.
>>
>> [1] is from the previous series. Actually, v2 for this one, addressing
>> the double-reissue bug found by Jens. It maybe not as efficient, but
>> simple and easy to backport.
>>
>> [2,3] current->mm NULL deref
> 
> And yet there are issues left... I'll resend

Can you also please have them separated in terms of what's for 5.8 and
what's for 5.9?

-- 
Jens Axboe


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, back to index

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-06-24 16:50 [PATCH 0/3] iopoll fixes Pavel Begunkov
2020-06-24 16:50 ` [PATCH 1/3] io_uring: fix hanging iopoll in case of -EAGAIN Pavel Begunkov
2020-06-24 16:50 ` [PATCH 2/3] io_uring: fix current->mm NULL dereference on exit Pavel Begunkov
2020-06-24 16:50 ` [PATCH 3/3] io_uring: fix NULL-mm for linked reqs Pavel Begunkov
2020-06-24 17:03 ` [PATCH 0/3] iopoll fixes Pavel Begunkov
2020-06-24 19:46   ` Jens Axboe

IO-Uring Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/io-uring/0 io-uring/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 io-uring io-uring/ https://lore.kernel.org/io-uring \
		io-uring@vger.kernel.org
	public-inbox-index io-uring

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.io-uring


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git