* [PATCH 0/2] post F_COMP_LOCKED optimisations
@ 2020-10-14 19:44 Pavel Begunkov
2020-10-14 19:44 ` [PATCH 1/2] io_uring: optimise COMP_LOCK-less flush_completion Pavel Begunkov
` (2 more replies)
0 siblings, 3 replies; 9+ messages in thread
From: Pavel Begunkov @ 2020-10-14 19:44 UTC (permalink / raw)
To: Jens Axboe, io-uring
A naive test with io_uring-bench with [nops, submit/complete batch=32]
shows 5500 vs 8500 KIOPS. Not really representative but might hurt if
left without [1/2].
Pavel Begunkov (2):
io_uring: optimise COMP_LOCK-less flush_completion
io_uring: optimise io_fail_links()
fs/io_uring.c | 24 ++++++++++++++++++++----
1 file changed, 20 insertions(+), 4 deletions(-)
--
2.24.0
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 1/2] io_uring: optimise COMP_LOCK-less flush_completion
2020-10-14 19:44 [PATCH 0/2] post F_COMP_LOCKED optimisations Pavel Begunkov
@ 2020-10-14 19:44 ` Pavel Begunkov
2020-10-14 19:44 ` [PATCH 2/2] io_uring: optimise io_fail_links() Pavel Begunkov
2020-10-14 19:53 ` [PATCH 0/2] post F_COMP_LOCKED optimisations Jens Axboe
2 siblings, 0 replies; 9+ messages in thread
From: Pavel Begunkov @ 2020-10-14 19:44 UTC (permalink / raw)
To: Jens Axboe, io-uring
After removing REQ_F_COMP_LOCKED io_submit_flush_completions() was left
deferring completions via task_work_add() in the hot path, that might
end up in a performance regression.
io_put_req() takes ->completion_lock only when at least one of
REQ_F_FAIL_LINK or REQ_F_LINK_TIMEOUT is set. There is also
REQ_F_WORK_INITIALIZED, freeing which while holding the lock have to be
avoided because it may deadlock with work.fs->lock. And if none of them
is set we can put under ->completion_lock and save an extra unlock/lock.
That actually works even better because it also works for most linked
requests unlike it was before.
Signed-off-by: Pavel Begunkov <[email protected]>
---
fs/io_uring.c | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/fs/io_uring.c b/fs/io_uring.c
index cb2640f6fdb2..f61af4d487fd 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -1601,12 +1601,19 @@ static void io_submit_flush_completions(struct io_comp_state *cs)
req = list_first_entry(&cs->list, struct io_kiocb, compl.list);
list_del(&req->compl.list);
__io_cqring_fill_event(req, req->result, req->compl.cflags);
- if (!(req->flags & REQ_F_LINK_HEAD)) {
- io_put_req_deferred(req, 1);
- } else {
+
+ /*
+ * io_free_req() doesn't care about completion_lock unless one
+ * of these flags is set. REQ_F_WORK_INITIALIZED is in the list
+ * because of a potential deadlock with req->work.fs->lock
+ */
+ if (req->flags & (REQ_F_FAIL_LINK|REQ_F_LINK_TIMEOUT
+ |REQ_F_WORK_INITIALIZED)) {
spin_unlock_irq(&ctx->completion_lock);
io_put_req(req);
spin_lock_irq(&ctx->completion_lock);
+ } else {
+ io_put_req(req);
}
}
io_commit_cqring(ctx);
--
2.24.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 2/2] io_uring: optimise io_fail_links()
2020-10-14 19:44 [PATCH 0/2] post F_COMP_LOCKED optimisations Pavel Begunkov
2020-10-14 19:44 ` [PATCH 1/2] io_uring: optimise COMP_LOCK-less flush_completion Pavel Begunkov
@ 2020-10-14 19:44 ` Pavel Begunkov
2020-10-15 8:53 ` Nathan Chancellor
2020-10-14 19:53 ` [PATCH 0/2] post F_COMP_LOCKED optimisations Jens Axboe
2 siblings, 1 reply; 9+ messages in thread
From: Pavel Begunkov @ 2020-10-14 19:44 UTC (permalink / raw)
To: Jens Axboe, io-uring
Optimise put handling in __io_fail_links() after removing
REQ_F_COMP_LOCKED.
Signed-off-by: Pavel Begunkov <[email protected]>
---
fs/io_uring.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/fs/io_uring.c b/fs/io_uring.c
index f61af4d487fd..271a016e8507 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -1816,7 +1816,16 @@ static void __io_fail_links(struct io_kiocb *req)
trace_io_uring_fail_link(req, link);
io_cqring_fill_event(link, -ECANCELED);
- io_put_req_deferred(link, 2);
+
+ /*
+ * It's ok to free under spinlock as they're not linked anymore,
+ * but avoid REQ_F_WORK_INITIALIZED because it may deadlock on
+ * work.fs->lock.
+ */
+ if (link->flags | REQ_F_WORK_INITIALIZED)
+ io_put_req_deferred(link, 2);
+ else
+ io_double_put_req(link);
}
io_commit_cqring(ctx);
--
2.24.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 0/2] post F_COMP_LOCKED optimisations
2020-10-14 19:44 [PATCH 0/2] post F_COMP_LOCKED optimisations Pavel Begunkov
2020-10-14 19:44 ` [PATCH 1/2] io_uring: optimise COMP_LOCK-less flush_completion Pavel Begunkov
2020-10-14 19:44 ` [PATCH 2/2] io_uring: optimise io_fail_links() Pavel Begunkov
@ 2020-10-14 19:53 ` Jens Axboe
2020-10-14 20:00 ` Pavel Begunkov
2 siblings, 1 reply; 9+ messages in thread
From: Jens Axboe @ 2020-10-14 19:53 UTC (permalink / raw)
To: Pavel Begunkov, io-uring
On 10/14/20 1:44 PM, Pavel Begunkov wrote:
> A naive test with io_uring-bench with [nops, submit/complete batch=32]
> shows 5500 vs 8500 KIOPS. Not really representative but might hurt if
> left without [1/2].
Part of this is undoubtedly that we only use the task_work for things
that need signaling, for the deferred put case we should be able to
get by with using notfy == 0 for task_work.
That said, it's nice to avoid when possible. At this point, I'd like
to fold these into the last patch of the original series. What do you
think?
--
Jens Axboe
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 0/2] post F_COMP_LOCKED optimisations
2020-10-14 19:53 ` [PATCH 0/2] post F_COMP_LOCKED optimisations Jens Axboe
@ 2020-10-14 20:00 ` Pavel Begunkov
2020-10-14 20:24 ` Jens Axboe
0 siblings, 1 reply; 9+ messages in thread
From: Pavel Begunkov @ 2020-10-14 20:00 UTC (permalink / raw)
To: Jens Axboe, io-uring
On 14/10/2020 20:53, Jens Axboe wrote:
> On 10/14/20 1:44 PM, Pavel Begunkov wrote:
>> A naive test with io_uring-bench with [nops, submit/complete batch=32]
>> shows 5500 vs 8500 KIOPS. Not really representative but might hurt if
>> left without [1/2].
>
> Part of this is undoubtedly that we only use the task_work for things
> that need signaling, for the deferred put case we should be able to
> get by with using notfy == 0 for task_work.
>
> That said, it's nice to avoid when possible. At this point, I'd like
> to fold these into the last patch of the original series. What do you
> think?
Yep, was thinking the same. It's better to be in 5.10, and that would
be easier to do by squashing.
--
Pavel Begunkov
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 0/2] post F_COMP_LOCKED optimisations
2020-10-14 20:00 ` Pavel Begunkov
@ 2020-10-14 20:24 ` Jens Axboe
0 siblings, 0 replies; 9+ messages in thread
From: Jens Axboe @ 2020-10-14 20:24 UTC (permalink / raw)
To: Pavel Begunkov, io-uring
On 10/14/20 2:00 PM, Pavel Begunkov wrote:
> On 14/10/2020 20:53, Jens Axboe wrote:
>> On 10/14/20 1:44 PM, Pavel Begunkov wrote:
>>> A naive test with io_uring-bench with [nops, submit/complete batch=32]
>>> shows 5500 vs 8500 KIOPS. Not really representative but might hurt if
>>> left without [1/2].
>>
>> Part of this is undoubtedly that we only use the task_work for things
>> that need signaling, for the deferred put case we should be able to
>> get by with using notfy == 0 for task_work.
>>
>> That said, it's nice to avoid when possible. At this point, I'd like
>> to fold these into the last patch of the original series. What do you
>> think?
>
> Yep, was thinking the same. It's better to be in 5.10, and that would
> be easier to do by squashing.
OK, done.
--
Jens Axboe
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 2/2] io_uring: optimise io_fail_links()
2020-10-14 19:44 ` [PATCH 2/2] io_uring: optimise io_fail_links() Pavel Begunkov
@ 2020-10-15 8:53 ` Nathan Chancellor
2020-10-15 10:11 ` Pavel Begunkov
0 siblings, 1 reply; 9+ messages in thread
From: Nathan Chancellor @ 2020-10-15 8:53 UTC (permalink / raw)
To: Pavel Begunkov; +Cc: Jens Axboe, io-uring, clang-built-linux
On Wed, Oct 14, 2020 at 08:44:22PM +0100, Pavel Begunkov wrote:
> Optimise put handling in __io_fail_links() after removing
> REQ_F_COMP_LOCKED.
>
> Signed-off-by: Pavel Begunkov <[email protected]>
> ---
> fs/io_uring.c | 11 ++++++++++-
> 1 file changed, 10 insertions(+), 1 deletion(-)
>
> diff --git a/fs/io_uring.c b/fs/io_uring.c
> index f61af4d487fd..271a016e8507 100644
> --- a/fs/io_uring.c
> +++ b/fs/io_uring.c
> @@ -1816,7 +1816,16 @@ static void __io_fail_links(struct io_kiocb *req)
> trace_io_uring_fail_link(req, link);
>
> io_cqring_fill_event(link, -ECANCELED);
> - io_put_req_deferred(link, 2);
> +
> + /*
> + * It's ok to free under spinlock as they're not linked anymore,
> + * but avoid REQ_F_WORK_INITIALIZED because it may deadlock on
> + * work.fs->lock.
> + */
> + if (link->flags | REQ_F_WORK_INITIALIZED)
> + io_put_req_deferred(link, 2);
> + else
> + io_double_put_req(link);
> }
>
> io_commit_cqring(ctx);
> --
> 2.24.0
>
This part of commit 9c357fed168a ("io_uring: fix REQ_F_COMP_LOCKED by
killing it") causes a clang warning:
fs/io_uring.c:1816:19: warning: bitwise or with non-zero value always
evaluates to true [-Wtautological-bitwise-compare]
if (link->flags | REQ_F_WORK_INITIALIZED)
~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
According to the comment, was it intended for that to be a bitwise AND
then negated to check for the absence of it? If so, wouldn't it be
clearer to flip the condition so that a negation is not necessary like
below? I can send a formal patch if my analysis is correct but if not,
feel free to fix it yourself and add
Reported-by: Nathan Chancellor <[email protected]>
diff --git a/fs/io_uring.c b/fs/io_uring.c
index 66c41d53a9d3..28b1a0fede3e 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -1813,10 +1813,10 @@ static void __io_fail_links(struct io_kiocb *req)
* but avoid REQ_F_WORK_INITIALIZED because it may deadlock on
* work.fs->lock.
*/
- if (link->flags | REQ_F_WORK_INITIALIZED)
- io_put_req_deferred(link, 2);
- else
+ if (link->flags & REQ_F_WORK_INITIALIZED)
io_double_put_req(link);
+ else
+ io_put_req_deferred(link, 2);
}
io_commit_cqring(ctx);
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 2/2] io_uring: optimise io_fail_links()
2020-10-15 8:53 ` Nathan Chancellor
@ 2020-10-15 10:11 ` Pavel Begunkov
2020-10-15 13:09 ` Jens Axboe
0 siblings, 1 reply; 9+ messages in thread
From: Pavel Begunkov @ 2020-10-15 10:11 UTC (permalink / raw)
To: Nathan Chancellor; +Cc: Jens Axboe, io-uring, clang-built-linux
On 15/10/2020 09:53, Nathan Chancellor wrote:
> On Wed, Oct 14, 2020 at 08:44:22PM +0100, Pavel Begunkov wrote:
>> - io_put_req_deferred(link, 2);
>> +
>> + /*
>> + * It's ok to free under spinlock as they're not linked anymore,
>> + * but avoid REQ_F_WORK_INITIALIZED because it may deadlock on
>> + * work.fs->lock.
>> + */
>> + if (link->flags | REQ_F_WORK_INITIALIZED)
>> + io_put_req_deferred(link, 2);
>> + else
>> + io_double_put_req(link);
>
> fs/io_uring.c:1816:19: warning: bitwise or with non-zero value always
> evaluates to true [-Wtautological-bitwise-compare]
> if (link->flags | REQ_F_WORK_INITIALIZED)
> ~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
> 1 warning generated.
>
> According to the comment, was it intended for that to be a bitwise AND
> then negated to check for the absence of it? If so, wouldn't it be
> clearer to flip the condition so that a negation is not necessary like
> below? I can send a formal patch if my analysis is correct but if not,
> feel free to fix it yourself and add
I have no idea what have happened, but yeah, there should be "&",
though without any additional negation. That's because deferred
version is safer.
Nathan, thanks for letting know!
Jens, could you please fold in the change below.
diff --git a/fs/io_uring.c b/fs/io_uring.c
index 66c41d53a9d3..2c83c2688ec5 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -1813,7 +1813,7 @@ static void __io_fail_links(struct io_kiocb *req)
* but avoid REQ_F_WORK_INITIALIZED because it may deadlock on
* work.fs->lock.
*/
- if (link->flags | REQ_F_WORK_INITIALIZED)
+ if (link->flags & REQ_F_WORK_INITIALIZED)
io_put_req_deferred(link, 2);
else
io_double_put_req(link);
--
Pavel Begunkov
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 2/2] io_uring: optimise io_fail_links()
2020-10-15 10:11 ` Pavel Begunkov
@ 2020-10-15 13:09 ` Jens Axboe
0 siblings, 0 replies; 9+ messages in thread
From: Jens Axboe @ 2020-10-15 13:09 UTC (permalink / raw)
To: Pavel Begunkov, Nathan Chancellor; +Cc: io-uring, clang-built-linux
On 10/15/20 4:11 AM, Pavel Begunkov wrote:
> On 15/10/2020 09:53, Nathan Chancellor wrote:
>> On Wed, Oct 14, 2020 at 08:44:22PM +0100, Pavel Begunkov wrote:
>>> - io_put_req_deferred(link, 2);
>>> +
>>> + /*
>>> + * It's ok to free under spinlock as they're not linked anymore,
>>> + * but avoid REQ_F_WORK_INITIALIZED because it may deadlock on
>>> + * work.fs->lock.
>>> + */
>>> + if (link->flags | REQ_F_WORK_INITIALIZED)
>>> + io_put_req_deferred(link, 2);
>>> + else
>>> + io_double_put_req(link);
>>
>> fs/io_uring.c:1816:19: warning: bitwise or with non-zero value always
>> evaluates to true [-Wtautological-bitwise-compare]
>> if (link->flags | REQ_F_WORK_INITIALIZED)
>> ~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
>> 1 warning generated.
>>
>> According to the comment, was it intended for that to be a bitwise AND
>> then negated to check for the absence of it? If so, wouldn't it be
>> clearer to flip the condition so that a negation is not necessary like
>> below? I can send a formal patch if my analysis is correct but if not,
>> feel free to fix it yourself and add
>
> I have no idea what have happened, but yeah, there should be "&",
> though without any additional negation. That's because deferred
> version is safer.
>
> Nathan, thanks for letting know!
> Jens, could you please fold in the change below.
Done.
--
Jens Axboe
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2020-10-15 13:09 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-10-14 19:44 [PATCH 0/2] post F_COMP_LOCKED optimisations Pavel Begunkov
2020-10-14 19:44 ` [PATCH 1/2] io_uring: optimise COMP_LOCK-less flush_completion Pavel Begunkov
2020-10-14 19:44 ` [PATCH 2/2] io_uring: optimise io_fail_links() Pavel Begunkov
2020-10-15 8:53 ` Nathan Chancellor
2020-10-15 10:11 ` Pavel Begunkov
2020-10-15 13:09 ` Jens Axboe
2020-10-14 19:53 ` [PATCH 0/2] post F_COMP_LOCKED optimisations Jens Axboe
2020-10-14 20:00 ` Pavel Begunkov
2020-10-14 20:24 ` Jens Axboe
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox