All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jens Axboe <axboe@kernel.dk>
To: Pavel Begunkov <asml.silence@gmail.com>, Ingo Molnar <mingo@kernel.org>
Cc: Ingo Molnar <mingo@redhat.com>,
	Peter Zijlstra <peterz@infradead.org>,
	linux-block@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH v2 0/2] Optimise io_uring completion waiting
Date: Mon, 23 Sep 2019 17:00:24 -0600	[thread overview]
Message-ID: <759b9b48-1de3-1d43-3e39-9c530bfffaa0@kernel.dk> (raw)
In-Reply-To: <731b2087-7786-5374-68ff-8cba42f0cd68@kernel.dk>

On 9/23/19 2:48 PM, Jens Axboe wrote:
> On 9/23/19 10:32 AM, Pavel Begunkov wrote:
>> Sorry, mixed the threads.
>>
>>>>
>>>> I'm not sure an extension is needed for such a special interface, why not
>>>> just put a ->threshold value next to the ctx->wait field and use either
>>>> the regular wait_event() APIs with the proper condition, or
>>>> wait_event_cmd() style APIs if you absolutely need something more complex
>>>> to happen inside?
>> Ingo,
>> io_uring works well without this patch just using wait_event_*() with
>> proper condition, but there are performance issues with spurious
>> wakeups. Detailed description in the previous mail.
>> Am I missing something?
> 
> I think we can do the same thing, just wrapping the waitqueue in a
> structure with a count in it, on the stack. Got some flight time
> coming up later today, let me try and cook up a patch.

Totally untested, and sent out 5 min before departure... But something
like this.


diff --git a/fs/io_uring.c b/fs/io_uring.c
index ca7570aca430..c2f9e1da26dd 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -2768,6 +2768,37 @@ static int io_ring_submit(struct io_ring_ctx *ctx, unsigned int to_submit,
 	return submit;
 }
 
+struct io_wait_queue {
+	struct wait_queue_entry wq;
+	struct io_ring_ctx *ctx;
+	struct task_struct *task;
+	unsigned to_wait;
+	unsigned nr_timeouts;
+};
+
+static inline bool io_should_wake(struct io_wait_queue *iowq)
+{
+	struct io_ring_ctx *ctx = iowq->ctx;
+
+	return io_cqring_events(ctx->rings) >= iowq->to_wait ||
+			atomic_read(&ctx->cq_timeouts) != iowq->nr_timeouts;
+}
+
+static int io_wake_function(struct wait_queue_entry *curr, unsigned int mode,
+			    int wake_flags, void *key)
+{
+	struct io_wait_queue *iowq = container_of(curr, struct io_wait_queue,
+							wq);
+
+	if (io_should_wake(iowq)) {
+		list_del_init(&curr->entry);
+		wake_up_process(iowq->task);
+		return 1;
+	}
+
+	return -1;
+}
+
 /*
  * Wait until events become available, if we don't already have some. The
  * application must reap them itself, as they reside on the shared cq ring.
@@ -2775,8 +2806,16 @@ static int io_ring_submit(struct io_ring_ctx *ctx, unsigned int to_submit,
 static int io_cqring_wait(struct io_ring_ctx *ctx, int min_events,
 			  const sigset_t __user *sig, size_t sigsz)
 {
+	struct io_wait_queue iowq = {
+		.wq = {
+			.func	= io_wake_function,
+			.entry	= LIST_HEAD_INIT(iowq.wq.entry),
+		},
+		.task		= current,
+		.ctx		= ctx,
+		.to_wait	= min_events,
+	};
 	struct io_rings *rings = ctx->rings;
-	unsigned nr_timeouts;
 	int ret;
 
 	if (io_cqring_events(rings) >= min_events)
@@ -2795,15 +2834,16 @@ static int io_cqring_wait(struct io_ring_ctx *ctx, int min_events,
 			return ret;
 	}
 
-	nr_timeouts = atomic_read(&ctx->cq_timeouts);
-	/*
-	 * Return if we have enough events, or if a timeout occured since
-	 * we started waiting. For timeouts, we always want to return to
-	 * userspace.
-	 */
-	ret = wait_event_interruptible(ctx->wait,
-				io_cqring_events(rings) >= min_events ||
-				atomic_read(&ctx->cq_timeouts) != nr_timeouts);
+	iowq.nr_timeouts = atomic_read(&ctx->cq_timeouts);
+	prepare_to_wait_exclusive(&ctx->wait, &iowq.wq, TASK_INTERRUPTIBLE);
+	do {
+		if (io_should_wake(&iowq))
+			break;
+		schedule();
+		set_current_state(TASK_INTERRUPTIBLE);
+	} while (1);
+	finish_wait(&ctx->wait, &iowq.wq);
+
 	restore_saved_sigmask_unless(ret == -ERESTARTSYS);
 	if (ret == -ERESTARTSYS)
 		ret = -EINTR;

-- 
Jens Axboe


  reply	other threads:[~2019-09-23 23:00 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-09-22  8:08 [PATCH v2 0/2] Optimise io_uring completion waiting Pavel Begunkov (Silence)
2019-09-22  8:08 ` [PATCH v2 1/2] sched/wait: Add wait_threshold Pavel Begunkov (Silence)
2019-09-23  7:19   ` Peter Zijlstra
2019-09-23 16:37     ` Pavel Begunkov
2019-09-23 19:27       ` Peter Zijlstra
2019-09-23 20:23         ` Peter Zijlstra
2019-09-24  6:44         ` Pavel Begunkov
2019-09-22  8:08 ` [PATCH v2 2/2] io_uring: Optimise cq waiting with wait_threshold Pavel Begunkov (Silence)
2019-09-22 15:51 ` [PATCH v2 0/2] Optimise io_uring completion waiting Jens Axboe
2019-09-23  8:35   ` Ingo Molnar
2019-09-23 16:21     ` Pavel Begunkov
2019-09-23 16:32       ` Pavel Begunkov
2019-09-23 20:48         ` Jens Axboe
2019-09-23 23:00           ` Jens Axboe [this message]
2019-09-24  7:06             ` Pavel Begunkov
2019-09-24  8:02               ` Jens Axboe
2019-09-24  8:27                 ` Jens Axboe
2019-09-24  8:36                   ` Jens Axboe
2019-09-24  9:33                     ` Pavel Begunkov
2019-09-24 10:11                       ` Jens Axboe
2019-09-24  9:49                     ` Peter Zijlstra
2019-09-24 10:13                       ` Jens Axboe
2019-09-24 10:34                         ` Jens Axboe
2019-09-24 11:11                           ` Pavel Begunkov
2019-09-24 11:15                             ` Jens Axboe
2019-09-24 11:23                               ` Pavel Begunkov
2019-09-24 13:13                                 ` Jens Axboe
2019-09-24 17:33                                   ` Pavel Begunkov
2019-09-24 17:46                                     ` Jens Axboe
2019-09-24 18:28                                       ` Pavel Begunkov
2019-09-24 19:32                                         ` Jens Axboe
2019-09-24 11:43                             ` Peter Zijlstra
2019-09-24 12:57                               ` Jens Axboe
2019-09-24 11:33                           ` Peter Zijlstra
2019-09-24  9:20                   ` Pavel Begunkov
2019-09-24 10:09                     ` Jens Axboe
2019-09-24  9:21                 ` Pavel Begunkov
2019-09-24 10:09                   ` Jens Axboe

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=759b9b48-1de3-1d43-3e39-9c530bfffaa0@kernel.dk \
    --to=axboe@kernel.dk \
    --cc=asml.silence@gmail.com \
    --cc=linux-block@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@kernel.org \
    --cc=mingo@redhat.com \
    --cc=peterz@infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.