diff mbox

[v6,7/7] scsi_io_completion convert BUGs to WARNs

Message ID 20180623102220.5438-8-dgilbert@interlog.com (mailing list archive)
State Accepted
Headers show

Commit Message

Douglas Gilbert June 23, 2018, 10:22 a.m. UTC
The scsi_io_completion function contains three BUG() and BUG_ON() calls.
Replace them with WARN variants.

Signed-off-by: Douglas Gilbert <dgilbert@interlog.com>
Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
Reviewed-by: Bart Van Assche <bart.vanassche@wdc.com>
---
 drivers/scsi/scsi_lib.c | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

Comments

Hannes Reinecke June 26, 2018, 5:28 a.m. UTC | #1
On 06/23/2018 12:22 PM, Douglas Gilbert wrote:
> The scsi_io_completion function contains three BUG() and BUG_ON() calls.
> Replace them with WARN variants.
> 
> Signed-off-by: Douglas Gilbert <dgilbert@interlog.com>
> Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
> Reviewed-by: Bart Van Assche <bart.vanassche@wdc.com>
> ---
>   drivers/scsi/scsi_lib.c | 15 ++++++++++++---
>   1 file changed, 12 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
> index 19ed11abe886..252edd61a688 100644
> --- a/drivers/scsi/scsi_lib.c
> +++ b/drivers/scsi/scsi_lib.c
> @@ -1060,13 +1060,21 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
>   			scsi_req(req->next_rq)->resid_len = scsi_in(cmd)->resid;
>   			if (scsi_end_request(req, BLK_STS_OK, blk_rq_bytes(req),
>   					blk_rq_bytes(req->next_rq)))
> -				BUG();
> +				WARN_ONCE(true,
> +					  "Bidi command with remaining bytes");
>   			return;
>   		}
>   	}
>   
>   	/* no bidi support yet, other than in pass-through */
> -	BUG_ON(blk_bidi_rq(req));
> +	if (unlikely(blk_bidi_rq(req))) {
> +		WARN_ONCE(true, "Only support bidi command in passthrough");
> +		scmd_printk(KERN_ERR, cmd, "Killing bidi command\n");
> +		if (scsi_end_request(req, BLK_STS_IOERR, blk_rq_bytes(req),
> +				     blk_rq_bytes(req->next_rq)))
> +			WARN_ONCE(true, "Bidi command with remaining bytes");
> +		return;
> +	}
>   
>   	/*
>   	 * Next deal with any sectors which we were able to correctly
> @@ -1089,7 +1097,8 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
>   	/* Kill remainder if no retries. */
>   	if (unlikely(blk_stat && scsi_noretry_cmd(cmd))) {
>   		if (scsi_end_request(req, blk_stat, blk_rq_bytes(req), 0))
> -			BUG();
> +			WARN_ONCE(true,
> +			    "Bytes remaining after failed, no-retry command");
>   		return;
>   	}
>   
> 
So what happens to these requests if not all bytes could be finished?
Do we have an error recovery strategy?
Changing to WARN_ON would only makes sense if we have a way of 
recovering the failed request, otherwise we'd have to reboot anyway, 
hence there wouldn't be much difference to the BUG() statement...

Cheers,

Hannes
Douglas Gilbert June 26, 2018, 10:53 a.m. UTC | #2
On 2018-06-26 07:28 AM, Hannes Reinecke wrote:
> On 06/23/2018 12:22 PM, Douglas Gilbert wrote:
>> The scsi_io_completion function contains three BUG() and BUG_ON() calls.
>> Replace them with WARN variants.
>>
>> Signed-off-by: Douglas Gilbert <dgilbert@interlog.com>
>> Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
>> Reviewed-by: Bart Van Assche <bart.vanassche@wdc.com>
>> ---
>>   drivers/scsi/scsi_lib.c | 15 ++++++++++++---
>>   1 file changed, 12 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
>> index 19ed11abe886..252edd61a688 100644
>> --- a/drivers/scsi/scsi_lib.c
>> +++ b/drivers/scsi/scsi_lib.c
>> @@ -1060,13 +1060,21 @@ void scsi_io_completion(struct scsi_cmnd *cmd, 
>> unsigned int good_bytes)
>>               scsi_req(req->next_rq)->resid_len = scsi_in(cmd)->resid;
>>               if (scsi_end_request(req, BLK_STS_OK, blk_rq_bytes(req),
>>                       blk_rq_bytes(req->next_rq)))
>> -                BUG();
>> +                WARN_ONCE(true,
>> +                      "Bidi command with remaining bytes");
>>               return;
>>           }
>>       }
>>       /* no bidi support yet, other than in pass-through */
>> -    BUG_ON(blk_bidi_rq(req));
>> +    if (unlikely(blk_bidi_rq(req))) {
>> +        WARN_ONCE(true, "Only support bidi command in passthrough");
>> +        scmd_printk(KERN_ERR, cmd, "Killing bidi command\n");
>> +        if (scsi_end_request(req, BLK_STS_IOERR, blk_rq_bytes(req),
>> +                     blk_rq_bytes(req->next_rq)))
>> +            WARN_ONCE(true, "Bidi command with remaining bytes");
>> +        return;
>> +    }
>>       /*
>>        * Next deal with any sectors which we were able to correctly
>> @@ -1089,7 +1097,8 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned 
>> int good_bytes)
>>       /* Kill remainder if no retries. */
>>       if (unlikely(blk_stat && scsi_noretry_cmd(cmd))) {
>>           if (scsi_end_request(req, blk_stat, blk_rq_bytes(req), 0))
>> -            BUG();
>> +            WARN_ONCE(true,
>> +                "Bytes remaining after failed, no-retry command");
>>           return;
>>       }
>>
> So what happens to these requests if not all bytes could be finished?
> Do we have an error recovery strategy?
> Changing to WARN_ON would only makes sense if we have a way of recovering the 
> failed request, otherwise we'd have to reboot anyway, hence there wouldn't be 
> much difference to the BUG() statement...

It's been a while now, but I think these BUGs were changed to WARNs due to
checkpatch.pl nagging. Not that I added the BUG statements, but my patch
moved them so checkpatch.pl felt that I owned them. Ahhh no, it was your
colleague Johannes Thumshirn.

The SCSI subsystem may not be the primary storage medium on a system, so
bringing down the system because the SCSI mid-level has an unrecoverable
error may be overkill. Think an embedded system with the rootfs on a
/dev/mmcblk<n>p<m> device with the only "SCSI" device being an external
USB port for a memory key (I was fighting with a 3D printer was just that
config a few days ago). Then the user plugs in the world's worst USB
key (billion of candidates). Isn't one error strategy just to report,
ignore and continue?

Doug Gilbert
Johannes Thumshirn June 26, 2018, 11:10 a.m. UTC | #3
On Tue, Jun 26, 2018 at 12:53:32PM +0200, Douglas Gilbert wrote:
> The SCSI subsystem may not be the primary storage medium on a system, so
> bringing down the system because the SCSI mid-level has an unrecoverable
> error may be overkill. Think an embedded system with the rootfs on a
> /dev/mmcblk<n>p<m> device with the only "SCSI" device being an external
> USB port for a memory key (I was fighting with a 3D printer was just that
> config a few days ago). Then the user plugs in the world's worst USB
> key (billion of candidates). Isn't one error strategy just to report,
> ignore and continue?

Exactly and even if SCSI is the primary storage medium BUG_ON()s are
just bad, sorry. It's always better to do error recovery then hard
crashing a machine as it may be able to write out logs when doing
error recovery so one actually has a chance debugging the reasons why
it happened.

Byte,
	Johannes
diff mbox

Patch

diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 19ed11abe886..252edd61a688 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -1060,13 +1060,21 @@  void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
 			scsi_req(req->next_rq)->resid_len = scsi_in(cmd)->resid;
 			if (scsi_end_request(req, BLK_STS_OK, blk_rq_bytes(req),
 					blk_rq_bytes(req->next_rq)))
-				BUG();
+				WARN_ONCE(true,
+					  "Bidi command with remaining bytes");
 			return;
 		}
 	}
 
 	/* no bidi support yet, other than in pass-through */
-	BUG_ON(blk_bidi_rq(req));
+	if (unlikely(blk_bidi_rq(req))) {
+		WARN_ONCE(true, "Only support bidi command in passthrough");
+		scmd_printk(KERN_ERR, cmd, "Killing bidi command\n");
+		if (scsi_end_request(req, BLK_STS_IOERR, blk_rq_bytes(req),
+				     blk_rq_bytes(req->next_rq)))
+			WARN_ONCE(true, "Bidi command with remaining bytes");
+		return;
+	}
 
 	/*
 	 * Next deal with any sectors which we were able to correctly
@@ -1089,7 +1097,8 @@  void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
 	/* Kill remainder if no retries. */
 	if (unlikely(blk_stat && scsi_noretry_cmd(cmd))) {
 		if (scsi_end_request(req, blk_stat, blk_rq_bytes(req), 0))
-			BUG();
+			WARN_ONCE(true,
+			    "Bytes remaining after failed, no-retry command");
 		return;
 	}