[PATCH] nvmet_fc: prevent new io rqsts in possible isr completions
James Smart
james.smart at broadcom.com
Thu Mar 1 07:04:29 PST 2018
On 3/1/2018 4:04 AM, Sagi Grimberg wrote:
> Hi James,
>
>> When a bio completion calls back into the transport for a
>> back-end io device, the request completion path can free
>> the transport io job structure allowing it to be reused for
>> other operations.
>
> Is this true doe something that is not aborted?
?? I think - it's true regardless of whether the link-side io was
aborted or not.
This is simply the bio completion path for say a read op, to get the
data so the
transport can send it.
>
>> The transport has a defer_rcv queue which
>> holds temporary cmd rcv ops while waitng for io job structures.
>> when the job frees, if there's a cmd waiting, it is picked up
>> and submitted for processing, which can call back out to the
>> bio path if it's a read. Unfortunately, what is unknown is the
>> context of the original bio done call, and it may be in a state
>> (softirq) that is not compatible with submitting the new bio in
>> the same calling sequence. This is especially true when using
>> scsi back-end devices as scsi is in softirq when it makes the
>> done call.
>>
>> Correct by scheduling the io to be started via workq rather
>> than calling the start new io path inline to the original bio
>> done path.
>
> Isn't free_iod called for every rsp completion? Is triggering defer_work
> unconditionally the optimal approach? In other words, won't that yield
> extra overhead in the "normal" case?
Yes, free_iod is on every completion. The check for defer_work is the
overhead on every io. However, in most cases, there is never deferred
work so the workq scheduling is rarely taken. If it is taken, I'm fine
with it always being a longer workq path.
The defer_rcv thing is an oddity about FC. In FC we really don't have
dedicated landing buffers for all cmds. The transport allocates a io job
struct for each SQ entry. But we found, the interaction with the lldd
around sending the rsp back allowed the rsp to go on the wire and the
initiator to send a new FC command, which could arrive before the
adapter serviced its interrupt and did all the handshaking with the
transport to return the job structure. So new cmd arrival beat free_iod
even when under queue size limits. This only happens when you are
hovering at 100% full on the SQ.
-- james
More information about the Linux-nvme
mailing list