From: Boaz Harrosh <bharrosh@panasas.com>
To: Miquel van Smoorenburg <mikevs@xs4all.net>
Cc: linux-scsi@vger.kernel.org,
James Bottomley <James.Bottomley@HansenPartnership.com>,
Jens Axboe <jens.axboe@oracle.com>
Subject: Re: 2.6.27 and good_bytes -= scsi_get_resid(cmd)
Date: Tue, 04 Nov 2008 10:32:50 +0200 [thread overview]
Message-ID: <491008B2.5030605@panasas.com> (raw)
In-Reply-To: <20081103215014.GA20035@xs4all.net>
Miquel van Smoorenburg wrote:
> I upgraded to 2.6.27 on a machine with the dpt_i2o scsi driver and
> I'm seeing some weird number from iostat -x 2. Basically it thinks
> that the size of every request is 32640 sectors (0xff0000 bytes),
> and that throws off the stats considerably.
>
> By using git-bisect I found out that the cause is this commit:
>
> commit 427e59f09fdba387547106de7bab980b7fff77be
> Author: James Bottomley <James.Bottomley@HansenPartnership.com>
> Date: Sat Mar 8 18:24:17 2008 -0600
>
> [SCSI] make use of the residue value
>
> USB sometimes doesn't return an error but instead returns a residue
> value indicating part (or all) of the command wasn't completed. So if
> the driver _done() error processing indicates the command was fully
> processed, subtract off the residue so that this USB error gets
> propagated.
>
> Cc: Alan Stern <stern@rowland.harvard.edu>
> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
>
> diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
> index 110e776..36c92f9 100644
> --- a/drivers/scsi/scsi.c
> +++ b/drivers/scsi/scsi.c
> @@ -855,9 +855,18 @@ void scsi_finish_command(struct scsi_cmnd *cmd)
>
> good_bytes = scsi_bufflen(cmd);
> if (cmd->request->cmd_type != REQ_TYPE_BLOCK_PC) {
> + int old_good_bytes = good_bytes;
> drv = scsi_cmd_to_driver(cmd);
> if (drv->done)
> good_bytes = drv->done(cmd);
> + /*
> + * USB may not give sense identifying bad sector and
> + * simply return a residue instead, so subtract off the
> + * residue if drv->done() error processing indicates no
> + * change to the completion length.
> + */
> + if (good_bytes == old_good_bytes)
> + good_bytes -= scsi_get_resid(cmd);
James hi. looking at this again it looks wrong to me. What are we
doing here? we are asking the remainder to be requeued again. Is
that the right thing to do? should we not raise an -EIO instead.
As the comments above states it is usually do to a bad sector.
I think the all decision should be moved into the drv->done
function, only it knows what the command was and what's relevant.
> }
> scsi_io_completion(cmd, good_bytes);
> }
>
>
> Now the dpt_i2o driver calls scsi_set_resid unconditionally after
> a command completes and comments it as '// calculate resid for sg' .
>
> Reverting the above commit fixes my problem. Applying the following
> patch to dpt_i2o.c fixes it as well. If the patch below is
> actually considered the right way to fix this (I'm not really sure
> what I'm doing here) then I think there might be more drivers that
> need a similar fix.
>
> [PATCH] dpt_i2o.c: calculate resid for sg only
>
> dpt_i2o.c calls scsi_set_resid() unconditionally. But
> it should only do that for sg requests. This became apparent
> after commit 427e59f09fdba387547106de7bab980b7fff77be .
>
> Signed-off-by: Miquel vam Smoorenburg <mikevs@xs4all.net>
>
> --- linux-2.6.27.4/drivers/scsi/dpt_i2o.c.ORIG 2008-10-26 00:05:07.000000000 +0200
> +++ linux-2.6.27.4/drivers/scsi/dpt_i2o.c 2008-11-03 22:17:21.000000000 +0100
> @@ -2445,7 +2445,8 @@
> hba_status = detailed_status >> 8;
>
> // calculate resid for sg
> - scsi_set_resid(cmd, scsi_bufflen(cmd) - readl(reply+5));
> + if (cmd->request->cmd_type == REQ_TYPE_BLOCK_PC)
> + scsi_set_resid(cmd, scsi_bufflen(cmd) - readl(reply+5));
>
Why does the readl(reply+5) does not return the same number as
scsi_bufflen(cmd). This is the real problem.
What you have done is just shove the problem away and never set
residual for normal read/write commands.
Someone that knows the HW should check out, how to read from
the device the real bytes transferred. Now if the real bytes
transferred is different then what was requested in CDB, the
HW should raise a CHECK_CONDITION status. If it does not then
this is the same broken state as those USB stuff, and perhaps
it should be looked into.
But I hope this is just bad programing on the driver's
part, which interprets wrongly the return value from the register.
Maybe the HW protocol mandates that the readl(reply+5) register.
(nice descriptive name) should only be read if the HW returned
CHECK_CONDITION, other wise it contains something else.
> pHba = (adpt_hba*) cmd->device->host->hostdata[0];
>
>
>
> Mike.
> --
Scsi-ml has changed, before it would disregard the residual
if no CHECK_CONDITION was raised. Now it will look at it all
the time. Which means drivers can not be sloppy about the resid
value any more.
Boaz
next prev parent reply other threads:[~2008-11-04 8:32 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-11-03 21:50 2.6.27 and good_bytes -= scsi_get_resid(cmd) Miquel van Smoorenburg
2008-11-04 8:32 ` Boaz Harrosh [this message]
2008-11-04 23:04 ` Miquel van Smoorenburg
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=491008B2.5030605@panasas.com \
--to=bharrosh@panasas.com \
--cc=James.Bottomley@HansenPartnership.com \
--cc=jens.axboe@oracle.com \
--cc=linux-scsi@vger.kernel.org \
--cc=mikevs@xs4all.net \
/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