All of lore.kernel.org
 help / color / mirror / Atom feed
From: Bijan Mottahedeh <bijan.mottahedeh@oracle.com>
To: Jens Axboe <axboe@kernel.dk>
Cc: linux-block@vger.kernel.org
Subject: Re: [RFC 0/2] io_uring: examine request result only after completion
Date: Thu, 24 Oct 2019 12:18:19 -0700	[thread overview]
Message-ID: <201931df-ae22-c2fc-a9c7-496ceb87dff7@oracle.com> (raw)
In-Reply-To: <22fc1057-237b-a9b8-5a57-b7c53166a609@kernel.dk>


On 10/24/19 10:09 AM, Jens Axboe wrote:
> On 10/24/19 3:18 AM, Bijan Mottahedeh wrote:
>> Running an fio test consistenly crashes the kernel with the trace included
>> below.  The root cause seems to be the code in __io_submit_sqe() that
>> checks the result of a request for -EAGAIN in polled mode, without
>> ensuring first that the request has completed:
>>
>> 	if (ctx->flags & IORING_SETUP_IOPOLL) {
>> 		if (req->result == -EAGAIN)
>> 			return -EAGAIN;
> I'm a little confused, because we should be holding the submission
> reference to the request still at this point. So how is it going away?
> I must be missing something...

I don't think the submission reference is going away...

I *think* the problem has to do with the fact that 
io_complete_rw_iopoll() which sets REQ_F_IOPOLL_COMPLETED is being 
called from interrupt context in my configuration and so there is a 
potential race between updating the request there and checking it in 
__io_submit_sqe().

My first workaround was to simply poll for REQ_F_IOPOLL_COMPLETED in the 
code snippet above:

     if (req->result == --EAGAIN) {

         poll for REQ_F_IOPOLL_COMPLETED

         return -EAGAIN;

}

and that got rid of the problem.

>
>> The request will be immediately resubmitted in io_sq_wq_submit_work(),
>> potentially before the the fisrt submission has completed.  This creates
>> a race where the original completion may set REQ_F_IOPOLL_COMPLETED in
>> a freed submission request, overwriting the poisoned bits, casusing the
>> panic below.
>>
>> 	do {
>> 		ret = __io_submit_sqe(ctx, req, s, false);
>> 		/*
>> 		 * We can get EAGAIN for polled IO even though
>> 		 * we're forcing a sync submission from here,
>> 		 * since we can't wait for request slots on the
>> 		 * block side.
>> 		 */
>> 		if (ret != -EAGAIN)
>> 			break;
>> 		cond_resched();
>> 	} while (1);
>>
>> The suggested fix is to move a submitted request to the poll list
>> unconditionally in polled mode.  The request can then be retried if
>> necessary once the original submission has indeed completed.
>>
>> This bug raises an issue however since REQ_F_IOPOLL_COMPLETED is set
>> in io_complete_rw_iopoll() from interrupt context.  NVMe polled queues
>> however are not supposed to generate interrupts so it is not clear what
>> is the reason for this apparent inconsitency.
> It's because you're not running with poll queues for NVMe, hence you're
> throwing a lot of performance away. Load nvme with poll_queues=X (or boot
> with nvme.poll_queues=X, if built in) to have a set of separate queues
> for polling. These don't have IRQs enabled, and it'll work much faster
> for you.
>
That's what I did in fact.  I booted with nvme.poll_queues=36 (I figured 
1 per core but I'm not sure what is a reasonable number).

I also checked that /sys/block/<nvme>/queue/io_poll = 1.

What's really odd is that the irq/sec numbers from mpstat and perf show 
equivalent values with/without polling (with/without fio "hipri" option) 
even though I can see from perf top that we are in fact polling in one 
case. I don't if I missing a step or something is off in my config.

Thanks.

--bijan


  reply	other threads:[~2019-10-24 19:18 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-10-24  9:18 [RFC 0/2] io_uring: examine request result only after completion Bijan Mottahedeh
2019-10-24  9:18 ` [RFC 1/2] io_uring: create io_queue_async() function Bijan Mottahedeh
2019-10-24  9:18 ` [RFC 2/2] io_uring: examine request result only after completion Bijan Mottahedeh
2019-10-24 17:09 ` [RFC 0/2] " Jens Axboe
2019-10-24 19:18   ` Bijan Mottahedeh [this message]
2019-10-24 22:31     ` Jens Axboe
     [not found]       ` <fa82e9fc-caf7-a94a-ebff-536413e9ecce@oracle.com>
2019-10-25 14:07         ` Jens Axboe
2019-10-25 14:18           ` Jens Axboe
2019-10-25 14:21             ` Jens Axboe
2019-10-29 19:17               ` Bijan Mottahedeh
2019-10-29 19:23                 ` Bijan Mottahedeh
2019-10-29 19:27                   ` Jens Axboe
2019-10-29 19:31                     ` Bijan Mottahedeh
2019-10-29 19:33                       ` Jens Axboe
2019-10-29 19:40                         ` Bijan Mottahedeh
2019-10-29 19:46                           ` Jens Axboe
2019-10-29 19:51                             ` Bijan Mottahedeh
2019-10-29 19:52                               ` Jens Axboe
2019-10-30  1:02                                 ` Jens Axboe
2019-10-30 14:02                                   ` Bijan Mottahedeh
2019-10-30 14:18                                     ` Jens Axboe
2019-10-30 17:32                                       ` Jens Axboe
2019-10-30 19:21                                         ` Bijan Mottahedeh
2019-10-30 19:26                                           ` Jens Axboe
2019-10-25 14:42             ` Bijan Mottahedeh

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=201931df-ae22-c2fc-a9c7-496ceb87dff7@oracle.com \
    --to=bijan.mottahedeh@oracle.com \
    --cc=axboe@kernel.dk \
    --cc=linux-block@vger.kernel.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.