[PATCH] nvme: allow timed-out ios to retry
James Smart
james.smart at broadcom.com
Mon Sep 18 10:15:45 PDT 2017
On 9/8/2017 9:11 AM, James Smart wrote:
> On 9/7/2017 1:37 PM, Keith Busch wrote:
>> On Thu, Sep 07, 2017 at 01:18:04PM -0700, James Smart wrote:
>>> Currently the nvme_req_needs_retry() applies several checks to see if
>>> a retry is allowed. On of those is whether the current time has
>>> exceeded
>>> the start time of the io plus the timeout length. This check, if an io
>>> times out, means there is never a retry allowed for the io. Which means
>>> applications see the io failure.
>>>
>>> Remove this check and allow the io to timeout, like it does on other
>>> protocols, and retries to be made.
>>>
>>> On the FC transport, a frame can be lost for an individual io, and
>>> there
>>> may be no other errors that escalate for the connection/association.
>>> The io will timeout, which causes the transport to escalate into
>>> creating
>>> a new association, but the io that timed out, due to this retry
>>> logic, has
>>> already failed back to the application and things are hosed.
>>
>> I'm a bit conflicted on this. While it'd be nice to give commands a
>> chance
>> to succeed after a timeout handling's controller reset, some uses would
>> rather a command fail fast than succeed slow, and this change could keep
>> a request outstanding for a very long time.
>>
>> What if we have a second timeout value: one for in-flight timeout before
>> abort/controller resset, and another for total request lifetime?
>
> I believe its mandatory to allow an in-flight timeout and at least 1
> retry, unless the io callee explicitly disables the retry. We can't
> make an enterprise-quality solution otherwise.
>
> I assume the existing NVME_IO_TIMEOUT value is what we continue to use
> for the in-flight timeout. "In-flight" defined as outstanding and
> waiting on the controller: i.e. placed on the SQ by the host/transport
> and no corresponding completion received from the controller.
>
> I'm ok with a lifetime timeout. But - is it necessary? Usually the
> lifetime timeout is (io timeout * # retries allowed) and it allows for
> slop as the "timeout" recovery isn't always immediate/instantaneous.
> In other words, Timeout will fire at time X, then the transport does
> what it needs to recover the io as of the timeout, which may take an
> additional amount of time Y, then the retry determinism kicks in. So
> it's not a hard M time ticks.
>
> Like SCSI added "fast_io_fail_tmo" to it's similar "blocked"
> conditions for an io - I expect we need a 3rd timeout for "fastfail".
> I/O is stopped/terminated when the controller is reset or reconnect
> started. If a further retry is not allowed, it will fail back to the
> callee. If a further retry is allowed, the io is queued on the blk
> queue, but the blk queue is stopped by the transport waits for
> controller reconnection. The fastfail timer would start as of the
> blocking of the blk queues. The timer would be cancelled if
> connectivity is restored and the blk queue released again allowing the
> io to be in-flight again. Timeout expiration would fail all pending io
> on the block queue with a connectivity status error and no further
> retries attempted.
>
>
> -- james
>
So where are we with this - what should be put in place ?
The one revision I'd make from above based is - we'd only apply this
timer on an I/O marked with a fastfail flag.
-- james
More information about the Linux-nvme
mailing list