All of lore.kernel.org
 help / color / mirror / Atom feed
From: Pavel Begunkov <asml.silence@gmail.com>
To: Ming Lei <ming.lei@redhat.com>
Cc: Jens Axboe <axboe@kernel.dk>,
	io-uring@vger.kernel.org, linux-block@vger.kernel.org,
	Kevin Wolf <kwolf@redhat.com>
Subject: Re: [PATCH V5 4/8] io_uring: support SQE group
Date: Tue, 10 Sep 2024 14:12:53 +0100	[thread overview]
Message-ID: <7050796e-be88-4e01-abdb-976baba2f83b@gmail.com> (raw)
In-Reply-To: <ZtweiCfLOJmdeY0Z@fedora>

On 9/7/24 10:36, Ming Lei wrote:
...
>>> Wrt. ublk, group provides zero copy, and the ublk io(group) is generic
>>> IO, sometime IO_LINK is really needed & helpful, such as in ublk-nbd,
>>> send(tcp) requests need to be linked & zc. And we shouldn't limit IO_LINK
>>> for generic io_uring IO.
>>>
>>>> from nuances as such, which would be quite hard to track, the semantics
>>>> of IOSQE_CQE_SKIP_SUCCESS is unclear.
>>>
>>> IO group just follows every normal request.
>>
>> It tries to mimic but groups don't and essentially can't do it the
>> same way, at least in some aspects. E.g. IOSQE_CQE_SKIP_SUCCESS
>> usually means that all following will be silenced. What if a
>> member is CQE_SKIP, should it stop the leader from posting a CQE?
>> And whatever the answer is, it'll be different from the link's
>> behaviour.
> 
> Here it looks easier than link's:
> 
> - only leader's IOSQE_CQE_SKIP_SUCCESS follows linked request's rule
> - all members just respects the flag for its own, and not related with
> leader's
> 
>>
>> Regardless, let's forbid IOSQE_CQE_SKIP_SUCCESS and linked timeouts
>> for groups, that can be discussed afterwards.
> 
> It should easy to forbid IOSQE_CQE_SKIP_SUCCESS which is per-sqe, will do
> it in V6.
> 
> I am not sure if it is easy to disallow IORING_OP_LINK_TIMEOUT, which
> covers all linked sqes, and group leader could be just one of them.
> Can you share any idea about the implementation to forbid LINK_TIMEOUT
> for sqe group?

diff --git a/io_uring/timeout.c b/io_uring/timeout.c
index 671d6093bf36..83b5fd64b4e9 100644
--- a/io_uring/timeout.c
+++ b/io_uring/timeout.c
@@ -542,6 +542,9 @@ static int __io_timeout_prep(struct io_kiocb *req,
  	data->mode = io_translate_timeout_mode(flags);
  	hrtimer_init(&data->timer, io_timeout_get_clock(data), data->mode);
  
+	if (is_timeout_link && req->ctx->submit_state.group.head)
+		return -EINVAL;
+
  	if (is_timeout_link) {
  		struct io_submit_link *link = &req->ctx->submit_state.link;
  

This should do, they already look into the ctx's link list. Just move
it into the "if (is_timeout_link)" block.


>>> 1) fail in linked chain
>>> - follows IO_LINK's behavior since io_fail_links() covers io group
>>>
>>> 2) otherwise
>>> - just respect IOSQE_CQE_SKIP_SUCCESS
>>>
>>>> And also it doen't work with IORING_OP_LINK_TIMEOUT.
>>>
>>> REQ_F_LINK_TIMEOUT can work on whole group(or group leader) only, and I
>>> will document it in V6.
>>
>> It would still be troublesome. When a linked timeout fires it searches
>> for the request it's attached to and cancels it, however, group leaders
>> that queued up their members are discoverable. But let's say you can find
>> them in some way, then the only sensbile thing to do is cancel members,
>> which should be doable by checking req->grp_leader, but might be easier
>> to leave it to follow up patches.
> 
> We have changed sqe group to start queuing members after leader is
> completed. link timeout will cancel leader with all its members via
> leader->grp_link, this behavior should respect IORING_OP_LINK_TIMEOUT
> completely.
> 
> Please see io_fail_links() and io_cancel_group_members().
> 
>>
>>
>>>>> +
>>>>> +		lead->grp_refs += 1;
>>>>> +		group->last->grp_link = req;
>>>>> +		group->last = req;
>>>>> +
>>>>> +		if (req->flags & REQ_F_SQE_GROUP)
>>>>> +			return NULL;
>>>>> +
>>>>> +		req->grp_link = NULL;
>>>>> +		req->flags |= REQ_F_SQE_GROUP;
>>>>> +		group->head = NULL;
>>>>> +		if (lead->flags & REQ_F_FAIL) {
>>>>> +			io_queue_sqe_fallback(lead);
>>>>
>>>> Let's say the group was in the middle of a link, it'll
>>>> complete that group and continue with assembling / executing
>>>> the link when it should've failed it and honoured the
>>>> request order.
>>>
>>> OK, here we can simply remove the above two lines, and link submit
>>> state can handle this failure in link chain.
>>
>> If you just delete then nobody would check for REQ_F_FAIL and
>> fail the request.
> 
> io_link_assembling() & io_link_sqe() checks for REQ_F_FAIL and call
> io_queue_sqe_fallback() either if it is in link chain or
> not.

The case we're talking about is failing a group, which is
also in the middle of a link.

LINK_HEAD -> {GROUP_LEAD, GROUP_MEMBER}

Let's say GROUP_MEMBER fails and sets REQ_F_FAIL to the lead,
then in v5 does:

if (lead->flags & REQ_F_FAIL) {
	io_queue_sqe_fallback(lead);
	return NULL;
}

In which case it posts cqes for GROUP_LEAD and GROUP_MEMBER,
and then try to execute LINK_HEAD (without failing it), which
is wrong. So first we need:

if (state.linked_link.head)
	req_fail_link_node(state.linked_link.head);

And then we can't just remove io_queue_sqe_fallback(), because
when a group is not linked there would be no io_link_sqe()
to fail it. You can do:


io_group_sqe()
{
	if ((lead->flags & REQ_F_FAIL) && !ctx->state.link.head) {
		io_queue_sqe_fallback(lead);
		return NULL;
	}
	...
}

but it's much cleaner to move REQ_F_FAIL out of group assembling.
We'd also want to move same REQ_F_FAIL / io_queue_sqe_fallback()
out of io_link_sqe(), but I didn't mentioned because it's not
strictly required for your set AFAIR.


>> Assuming you'd also set the fail flag to the
>> link head when appropriate, how about deleting these two line
>> and do like below? (can be further prettified)
>>
>>
>> bool io_group_assembling()
>> {
>> 	return state->group.head || (req->flags & REQ_F_SQE_GROUP);
>> }
>> bool io_link_assembling()
>> {
>> 	return state->link.head || (req->flags & IO_REQ_LINK_FLAGS);
>> }
>>
>> static inline int io_submit_sqe()
>> {
>> 	...
>> 	if (unlikely(io_link_assembling(state, req) ||
>> 				 io_group_assembling(state, req) ||
>> 				 req->flags & REQ_F_FAIL)) {
>> 		if (io_group_assembling(state, req)) {
>> 			req = io_group_sqe(&state->group, req);
>> 			if (!req)
>> 				return 0;
>> 		}
>> 		if (io_link_assembling(state, req)) {
>> 			req = io_link_sqe(&state->link, req);
>> 			if (!req)
>> 				return 0;
>> 		}
>> 		if (req->flags & REQ_F_FAIL) {
>> 			io_queue_sqe_fallback(req);
>> 			return 0;
> 
> As I mentioned above, io_link_assembling() & io_link_sqe() covers
> the failure handling.

-- 
Pavel Begunkov

  reply	other threads:[~2024-09-10 13:12 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-08-08 16:24 [PATCH V5 0/8] io_uring: support sqe group and provide group kbuf Ming Lei
2024-08-08 16:24 ` [PATCH V5 1/8] io_uring: add io_link_req() helper Ming Lei
2024-08-08 16:24 ` [PATCH V5 2/8] io_uring: add io_submit_fail_link() helper Ming Lei
2024-08-08 16:24 ` [PATCH V5 3/8] io_uring: add helper of io_req_commit_cqe() Ming Lei
2024-08-08 16:24 ` [PATCH V5 4/8] io_uring: support SQE group Ming Lei
2024-08-27 15:18   ` Pavel Begunkov
2024-08-29  4:29     ` Ming Lei
2024-09-06 17:15       ` Pavel Begunkov
2024-09-07  9:36         ` Ming Lei
2024-09-10 13:12           ` Pavel Begunkov [this message]
2024-09-10 15:04             ` Ming Lei
2024-09-10 20:31               ` Pavel Begunkov
2024-09-11  1:28                 ` Ming Lei
2024-08-08 16:24 ` [PATCH V5 5/8] io_uring: support sqe group with members depending on leader Ming Lei
2024-08-08 16:24 ` [PATCH V5 6/8] io_uring: support providing sqe group buffer Ming Lei
2024-08-08 16:24 ` [PATCH V5 7/8] io_uring/uring_cmd: support provide group kernel buffer Ming Lei
2024-08-08 16:24 ` [PATCH V5 8/8] ublk: support provide io buffer Ming Lei
2024-08-17  4:16 ` [PATCH V5 0/8] io_uring: support sqe group and provide group kbuf Ming Lei
2024-08-17 19:48   ` Pavel Begunkov

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=7050796e-be88-4e01-abdb-976baba2f83b@gmail.com \
    --to=asml.silence@gmail.com \
    --cc=axboe@kernel.dk \
    --cc=io-uring@vger.kernel.org \
    --cc=kwolf@redhat.com \
    --cc=linux-block@vger.kernel.org \
    --cc=ming.lei@redhat.com \
    /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.