public inbox for linux-scsi@vger.kernel.org
 help / color / mirror / Atom feed
From: Patrick Mansfield <patmans@us.ibm.com>
To: Alan Stern <stern@rowland.harvard.edu>
Cc: James Bottomley <James.Bottomley@SteelEye.com>,
	Doug Gilbert <dgilbert@interlog.com>,
	SCSI development list <linux-scsi@vger.kernel.org>
Subject: Re: sg driver and the error handler
Date: Tue, 10 May 2005 15:58:31 -0700	[thread overview]
Message-ID: <20050510225831.GA4181@us.ibm.com> (raw)
In-Reply-To: <Pine.LNX.4.44L0.0505101433520.5058-100000@iolanthe.rowland.org>

Hi Alan -

On Tue, May 10, 2005 at 02:51:44PM -0400, Alan Stern wrote:
> When a command injected through the sg driver encounters any sort of
> error, the usual retry mechanism and error handler are brought into play.  
> Since sg sets the number of retries to 0 by default, the retry mechanism
> shouldn't cause any difficulty.  But the error handler does.  IMO it
> should never get involved with requests coming through sg -- sg should
> provide access that is as transparent as possible so that userspace
> programs will have a clean shot at managing their device.

The error handler is mainly a timeout handler, so it has to run to cancel
the timed out command, we can't complete the timed out command back to the
upper level until we know the HBA is no longer using it.

> Consider a case that just came up.  A USB CD drive causes a phase error
> when it receives a certain READ BUFFER command (buggy firmware on the
> drive, never mind that now).  You would expect the user program to receive
> from sg a host_status value indicating DID_ERROR or something of the sort.
> 
> Instead the error handler takes charge and sends out one or two TEST UNIT 
> READY commands.  The status information finally received by the user 
> program is the status from the TEST UNIT READY, not from the failed READ 
> BUFFER!  How's a program supposed to cope with that sort of obfuscation?

:-(

> Something in the SCSI stack (scsi_io_completion ?) should check for 
> requests coming in via sg and should know to complete the requests 
> immediately.  No requeuing and no error handling.

> Does this sound like a feasible thing to implement?

No per above. I think there are still some cases where sg or SG_IO
commands are not immediately returned, I think for some certain ASC codes,
some of those probably should be retried, as should cases like QUEUE FULL.

As you say, what you really want is the correct result going back to the
user, not the result of the TUR.

So save and restore the result in scsi_eh_tur, and also in scsi_eh_try_stu.
The request sense one already saves and restores it.

And always set result |= (DRIVER_TIMEOUT << 24) if we are not requeueing
the IO.

Like (only compile tested) this, against scsi-misc git tree of a few days
ago. Hopefully, sg or SG_IO programs can handle DRIVER_TIMEOUT :-/ but it
is certainly better than returning as if no error occurred.

What do you think?

diff -uprN -X /home/patman/dontdiff scsi-misc-2.6.git/drivers/scsi/scsi_error.c to-res-scsi-misc-2.6.git/drivers/scsi/scsi_error.c
--- scsi-misc-2.6.git/drivers/scsi/scsi_error.c	2005-05-09 14:19:41.000000000 -0700
+++ to-res-scsi-misc-2.6.git/drivers/scsi/scsi_error.c	2005-05-10 15:49:01.000000000 -0700
@@ -770,6 +770,7 @@ static int scsi_eh_tur(struct scsi_cmnd 
 {
 	static unsigned char tur_command[6] = {TEST_UNIT_READY, 0, 0, 0, 0, 0};
 	int retry_cnt = 1, rtn;
+	int saved_result;
 
 retry_tur:
 	memcpy(scmd->cmnd, tur_command, sizeof(tur_command));
@@ -780,6 +781,7 @@ retry_tur:
 	 */
 	memset(scmd->sense_buffer, 0, sizeof(scmd->sense_buffer));
 
+	saved_result = scmd->result;
 	scmd->request_buffer = NULL;
 	scmd->request_bufflen = 0;
 	scmd->use_sg = 0;
@@ -794,6 +796,7 @@ retry_tur:
 	 * the original request, so let's restore the original data. (db)
 	 */
 	scsi_setup_cmd_retry(scmd);
+	scmd->result = saved_result;
 
 	/*
 	 * hey, we are done.  let's look to see what happened.
@@ -896,6 +899,7 @@ static int scsi_eh_try_stu(struct scsi_c
 {
 	static unsigned char stu_command[6] = {START_STOP, 0, 0, 0, 1, 0};
 	int rtn;
+	int saved_result;
 
 	if (!scmd->device->allow_restart)
 		return 1;
@@ -908,6 +912,7 @@ static int scsi_eh_try_stu(struct scsi_c
 	 */
 	memset(scmd->sense_buffer, 0, sizeof(scmd->sense_buffer));
 
+	saved_result = scmd->result;
 	scmd->request_buffer = NULL;
 	scmd->request_bufflen = 0;
 	scmd->use_sg = 0;
@@ -922,6 +927,7 @@ static int scsi_eh_try_stu(struct scsi_c
 	 * the original request, so let's restore the original data. (db)
 	 */
 	scsi_setup_cmd_retry(scmd);
+	scmd->result = saved_result;
 
 	/*
 	 * hey, we are done.  let's look to see what happened.
@@ -1561,8 +1567,7 @@ static void scsi_eh_flush_done_q(struct 
 							  scmd));
 				scsi_queue_insert(scmd, SCSI_MLQUEUE_EH_RETRY);
 		} else {
-			if (!scmd->result)
-				scmd->result |= (DRIVER_TIMEOUT << 24);
+			scmd->result |= (DRIVER_TIMEOUT << 24);
 			SCSI_LOG_ERROR_RECOVERY(3, printk("%s: flush finish"
 							" cmd: %p\n",
 							current->comm, scmd));


-- Patrick Mansfield

  reply	other threads:[~2005-05-10 22:58 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-05-10 18:51 sg driver and the error handler Alan Stern
2005-05-10 22:58 ` Patrick Mansfield [this message]
2005-05-11 11:59   ` Douglas Gilbert
2005-05-11 16:35     ` Luben Tuikov
2005-05-11 17:45       ` Patrick Mansfield
2005-05-11 17:55         ` Luben Tuikov
2005-05-11 18:02           ` Patrick Mansfield
2005-05-11 19:43       ` Alan Stern
2005-05-11 16:40   ` Luben Tuikov
2005-05-11 17:14     ` Patrick Mansfield
2005-05-16 17:42   ` [PATCH] saved and restore result for timed out commands Patrick Mansfield
2005-05-16 19:42     ` Alan Stern
2005-06-01 18:45     ` Alan Stern
2005-06-01 21:00       ` James Bottomley
2005-06-01 21:26         ` Alan Stern
2005-06-01 21:57           ` Patrick Mansfield
2005-06-03 15:21           ` James Bottomley
2005-06-03 15:35             ` Alan Stern

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=20050510225831.GA4181@us.ibm.com \
    --to=patmans@us.ibm.com \
    --cc=James.Bottomley@SteelEye.com \
    --cc=dgilbert@interlog.com \
    --cc=linux-scsi@vger.kernel.org \
    --cc=stern@rowland.harvard.edu \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox