diff mbox

[v1,10/13] IB/iser: Support T10-PI operations

Message ID 5315A3E4.508@dev.mellanox.co.il (mailing list archive)
State Superseded, archived
Headers show

Commit Message

Sagi Grimberg March 4, 2014, 9:59 a.m. UTC
On 3/4/2014 11:38 AM, Or Gerlitz wrote:
> On 03/03/2014 06:44, Mike Christie wrote:
>> The xmit_task callout does handle failures like EINVAL. If the above map
>> calls fail then you would get infinite retries. You would currently want
>> to do the mapping in the init_task callout instead.
>>
>> If it makes it easier on the driver implementation then it is ok to
>> modify the xmit_task callers so that they handle multiple error codes
>> for drivers like iser that have the xmit_task callout called from
>> iscsi_queuecommand.
>
> Mike,
>
> After looking on the code with Sagi,  it seems to us that the correct 
> way to go here, would be to enhance in iscsi_queuecommand the 
> processing of the result returned by session->tt->xmit_task(task) to 
> behave in a similar manner to how the return value of 
> iscsi_prep_scsi_cmd_pdu() is treated. E.g for errors such as ENOMEM 
> and EGAIN take the "reject" flow which would cause the SCSI midlayer 
> to retry the command and for other return values go to the "fault" 
> flow which will cause the ML to abort the command.
>
> Or.
>

Yes, we were thinking about the following:
                 list_add_tail(&task->running, &conn->cmdqueue);

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Comments

Or Gerlitz March 4, 2014, 11:25 a.m. UTC | #1
On 04/03/2014 11:59, Sagi Grimberg wrote:
> On 3/4/2014 11:38 AM, Or Gerlitz wrote:
>> On 03/03/2014 06:44, Mike Christie wrote:
>>> The xmit_task callout does handle failures like EINVAL. If the above 
>>> map
>>> calls fail then you would get infinite retries. You would currently 
>>> want
>>> to do the mapping in the init_task callout instead.
>>>
>>> If it makes it easier on the driver implementation then it is ok to
>>> modify the xmit_task callers so that they handle multiple error codes
>>> for drivers like iser that have the xmit_task callout called from
>>> iscsi_queuecommand.
>>
>> Mike,
>>
>> After looking on the code with Sagi,  it seems to us that the correct 
>> way to go here, would be to enhance in iscsi_queuecommand the 
>> processing of the result returned by session->tt->xmit_task(task) to 
>> behave in a similar manner to how the return value of 
>> iscsi_prep_scsi_cmd_pdu() is treated. E.g for errors such as ENOMEM 
>> and EGAIN take the "reject" flow which would cause the SCSI midlayer 
>> to retry the command and for other return values go to the "fault" 
>> flow which will cause the ML to abort the command.
>>
>> Or.
>>
>
> Yes, we were thinking about the following:
> --- a/drivers/scsi/libiscsi.c
> +++ b/drivers/scsi/libiscsi.c
> @@ -1707,10 +1707,17 @@ int iscsi_queuecommand(struct Scsi_Host *host, 
> struct scsi_cmnd *sc)
>                                 goto prepd_fault;
>                         }
>                 }
> -               if (session->tt->xmit_task(task)) {
> -                       session->cmdsn--;
> -                       reason = FAILURE_SESSION_NOT_READY;
> -                       goto prepd_reject;
> +
> +               reason = session->tt->xmit_task(task);
> +               if (reason) {
> +                       if (reason == -ENOMEM || reason == -EAGAIN) {
> +                               session->cmdsn--;

I am pretty sure this has to be done anyway, no matter why the xmit_task 
callback failed

> + reason = FAILURE_SESSION_NOT_READY;
> +                               goto prepd_reject;
> +                       } else {
> +                               sc->result = DID_ABORT << 16;
> +                               goto prepd_fault;
> +                       }
>                 }
>         } else {
>                 list_add_tail(&task->running, &conn->cmdqueue);
>
> -- 
> To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Sagi Grimberg March 4, 2014, 2:44 p.m. UTC | #2
On 3/4/2014 1:25 PM, Or Gerlitz wrote:
> On 04/03/2014 11:59, Sagi Grimberg wrote:
>> On 3/4/2014 11:38 AM, Or Gerlitz wrote:
>>> On 03/03/2014 06:44, Mike Christie wrote:
>>>> The xmit_task callout does handle failures like EINVAL. If the 
>>>> above map
>>>> calls fail then you would get infinite retries. You would currently 
>>>> want
>>>> to do the mapping in the init_task callout instead.
>>>>
>>>> If it makes it easier on the driver implementation then it is ok to
>>>> modify the xmit_task callers so that they handle multiple error codes
>>>> for drivers like iser that have the xmit_task callout called from
>>>> iscsi_queuecommand.
>>>
>>> Mike,
>>>
>>> After looking on the code with Sagi,  it seems to us that the 
>>> correct way to go here, would be to enhance in iscsi_queuecommand 
>>> the processing of the result returned by 
>>> session->tt->xmit_task(task) to behave in a similar manner to how 
>>> the return value of iscsi_prep_scsi_cmd_pdu() is treated. E.g for 
>>> errors such as ENOMEM and EGAIN take the "reject" flow which would 
>>> cause the SCSI midlayer to retry the command and for other return 
>>> values go to the "fault" flow which will cause the ML to abort the 
>>> command.
>>>
>>> Or.
>>>
>>
>> Yes, we were thinking about the following:
>> --- a/drivers/scsi/libiscsi.c
>> +++ b/drivers/scsi/libiscsi.c
>> @@ -1707,10 +1707,17 @@ int iscsi_queuecommand(struct Scsi_Host 
>> *host, struct scsi_cmnd *sc)
>>                                 goto prepd_fault;
>>                         }
>>                 }
>> -               if (session->tt->xmit_task(task)) {
>> -                       session->cmdsn--;
>> -                       reason = FAILURE_SESSION_NOT_READY;
>> -                       goto prepd_reject;
>> +
>> +               reason = session->tt->xmit_task(task);
>> +               if (reason) {
>> +                       if (reason == -ENOMEM || reason == -EAGAIN) {
>> +                               session->cmdsn--;
>
> I am pretty sure this has to be done anyway, no matter why the 
> xmit_task callback failed

Even if we abort? this just follows the same logic as 
iscsi_prep_scsi_cmd_pdu error flow.

>
>> + reason = FAILURE_SESSION_NOT_READY;
>> +                               goto prepd_reject;
>> +                       } else {
>> +                               sc->result = DID_ABORT << 16;
>> +                               goto prepd_fault;
>> +                       }
>>                 }
>>         } else {
>>                 list_add_tail(&task->running, &conn->cmdqueue);
>>
>> -- 
>> To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Or Gerlitz March 4, 2014, 4:16 p.m. UTC | #3
On 04/03/2014 16:44, Sagi Grimberg wrote:
>>> @@ -1707,10 +1707,17 @@ int iscsi_queuecommand(struct Scsi_Host 
>>> *host, struct scsi_cmnd *sc)
>>>                                 goto prepd_fault;
>>>                         }
>>>                 }
>>> -               if (session->tt->xmit_task(task)) {
>>> -                       session->cmdsn--;
>>> -                       reason = FAILURE_SESSION_NOT_READY;
>>> -                       goto prepd_reject;
>>> +
>>> +               reason = session->tt->xmit_task(task);
>>> +               if (reason) {
>>> +                       if (reason == -ENOMEM || reason == -EAGAIN) {
>>> +                               session->cmdsn--;
>>
>> I am pretty sure this has to be done anyway, no matter why the 
>> xmit_task callback failed
>
> Even if we abort? this just follows the same logic as 
> iscsi_prep_scsi_cmd_pdu error flow.

yes, take a 2nd look on iscsi_prep_scsi_cmd_pdu and you'll see that all 
the possible error cases take place **before** session->cmdsn is 
incremented
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Sagi Grimberg March 4, 2014, 5:04 p.m. UTC | #4
On 3/4/2014 6:16 PM, Or Gerlitz wrote:
> On 04/03/2014 16:44, Sagi Grimberg wrote:
>>>> @@ -1707,10 +1707,17 @@ int iscsi_queuecommand(struct Scsi_Host 
>>>> *host, struct scsi_cmnd *sc)
>>>>                                 goto prepd_fault;
>>>>                         }
>>>>                 }
>>>> -               if (session->tt->xmit_task(task)) {
>>>> -                       session->cmdsn--;
>>>> -                       reason = FAILURE_SESSION_NOT_READY;
>>>> -                       goto prepd_reject;
>>>> +
>>>> +               reason = session->tt->xmit_task(task);
>>>> +               if (reason) {
>>>> +                       if (reason == -ENOMEM || reason == -EAGAIN) {
>>>> +                               session->cmdsn--;
>>>
>>> I am pretty sure this has to be done anyway, no matter why the 
>>> xmit_task callback failed
>>
>> Even if we abort? this just follows the same logic as 
>> iscsi_prep_scsi_cmd_pdu error flow.
>
> yes, take a 2nd look on iscsi_prep_scsi_cmd_pdu and you'll see that 
> all the possible error cases take place **before** session->cmdsn is 
> incremented

Ahhh, yes... So dec the cmdsn regardless.

Mike, are you on board with this?

Sagi.
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Mike Christie March 5, 2014, 5:55 p.m. UTC | #5
On 03/04/2014 03:59 AM, Sagi Grimberg wrote:
> On 3/4/2014 11:38 AM, Or Gerlitz wrote:
>> On 03/03/2014 06:44, Mike Christie wrote:
>>> The xmit_task callout does handle failures like EINVAL. If the above map
>>> calls fail then you would get infinite retries. You would currently want
>>> to do the mapping in the init_task callout instead.
>>>
>>> If it makes it easier on the driver implementation then it is ok to
>>> modify the xmit_task callers so that they handle multiple error codes
>>> for drivers like iser that have the xmit_task callout called from
>>> iscsi_queuecommand.
>>
>> Mike,
>>
>> After looking on the code with Sagi,  it seems to us that the correct
>> way to go here, would be to enhance in iscsi_queuecommand the
>> processing of the result returned by session->tt->xmit_task(task) to
>> behave in a similar manner to how the return value of
>> iscsi_prep_scsi_cmd_pdu() is treated. E.g for errors such as ENOMEM
>> and EGAIN take the "reject" flow which would cause the SCSI midlayer
>> to retry the command and for other return values go to the "fault"
>> flow which will cause the ML to abort the command.
>>
>> Or.
>>
> 
> Yes, we were thinking about the following:
> --- a/drivers/scsi/libiscsi.c
> +++ b/drivers/scsi/libiscsi.c
> @@ -1707,10 +1707,17 @@ int iscsi_queuecommand(struct Scsi_Host *host,
> struct scsi_cmnd *sc)
>                                 goto prepd_fault;
>                         }
>                 }
> -               if (session->tt->xmit_task(task)) {
> -                       session->cmdsn--;
> -                       reason = FAILURE_SESSION_NOT_READY;
> -                       goto prepd_reject;
> +
> +               reason = session->tt->xmit_task(task);
> +               if (reason) {
> +                       if (reason == -ENOMEM || reason == -EAGAIN) {
> +                               session->cmdsn--;
> +                               reason = FAILURE_SESSION_NOT_READY;
> +                               goto prepd_reject;
> +                       } else {
> +                               sc->result = DID_ABORT << 16;
> +                               goto prepd_fault;
> +                       }

Or is correct.

If iscsi_prep_scsi_cmd_pdu is successful then it will increment cmdsn.

In this code path for xmit_task above, we assume that the driver can
either take the entire command and can send it here, or return error and
we requeue. For your new error case where we cannot send the command due
to a hard failure so we want to fail the command, then we still need to
decrement the cmdsn or there would be a hole since it was never put on
the wire.

Also, it is probably safest to check for the error code you are adding
support for:

reason = session->tt->xmit_task(task);
if (reason) {
	session->cmdsn--;

	if (reason == -EINVAL) {
		sc->result = DID_ABORT << 16;
		goto prepd_fault;
	} else {
		sc->result = DID_ABORT << 16;
		goto prepd_fault;
	}
}
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -1707,10 +1707,17 @@  int iscsi_queuecommand(struct Scsi_Host *host, 
struct scsi_cmnd *sc)
                                 goto prepd_fault;
                         }
                 }
-               if (session->tt->xmit_task(task)) {
-                       session->cmdsn--;
-                       reason = FAILURE_SESSION_NOT_READY;
-                       goto prepd_reject;
+
+               reason = session->tt->xmit_task(task);
+               if (reason) {
+                       if (reason == -ENOMEM || reason == -EAGAIN) {
+                               session->cmdsn--;
+                               reason = FAILURE_SESSION_NOT_READY;
+                               goto prepd_reject;
+                       } else {
+                               sc->result = DID_ABORT << 16;
+                               goto prepd_fault;
+                       }
                 }
         } else {