Re: 2.6.24-rc4-mm1: hostbyte=0x01 driverbyte=0x00 (now bisected)

Alexey Dobriyan
2007-12-06T19:20:17Z

On Thu, Dec 06, 2007 at 08:52:29AM +0100, Hannes Reinecke wrote:
> Alexey Dobriyan wrote:
> >> git-scsi-misc.patch
> >
> > Apologies for not looking into the problem earlier. See
> > http://marc.info/?t=119628022300005&r=1&w=2
> > "2.6.24-rc3-mm2: Result: hostbyte=0x01 driverbyte=0x00\nend_request: I/O error"
> > for previous installment.
> >
> > I've bisected it to the following patch in git-scsi-misc branch.
> > Revert on top of 2.6.24-rc4-mm1 also helps.
> >
> > commit 8655a546c83fc43f0a73416bbd126d02de7ad6c0
> > Author: Hannes Reinecke <hare@suse.de>
> > Date: Tue Nov 6 09:23:40 2007 +0100
> >
> > [SCSI] Do not requeue requests if REQ_FAILFAST is set
> >
> > Any requests with the REQ_FAILFAST flag set should not be requeued
> > to the requeust queue, but rather terminated directly.
> > Otherwise the multipath failover will stall until the command
> > timeout triggers.
> >
> > Signed-off-by: Hannes Reinecke <hare@suse.de>
> > Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
> >
> > diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
> > index 0f44bdb..0da0dd0 100644
> > --- a/drivers/scsi/scsi_lib.c
> > +++ b/drivers/scsi/scsi_lib.c
> > @@ -1286,6 +1286,11 @@ int scsi_prep_state_check(struct scsi_device *sdev, struct request *req)
> > */
> > if (!(req->cmd_flags & REQ_PREEMPT))
> > ret = BLKPREP_DEFER;
> > + /*
> > + * Return failfast requests immediately
> > + */
> > + if (req->cmd_flags & REQ_FAILFAST)
> > + ret = BLKPREP_KILL;
> > break;
> > default:
> > /*
> > @@ -1414,6 +1419,17 @@ static inline int scsi_host_queue_ready(struct request_queue *q,
> > return 1;
> > }
> >
> > +static void __scsi_kill_request(struct request *req)
> > +{
> > + struct scsi_cmnd *cmd = req->special;
> > + struct scsi_device *sdev = cmd->device;
> > +
> > + cmd->result = DID_NO_CONNECT << 16;
> > + atomic_inc(&cmd->device->iorequest_cnt);
> > + sdev->device_busy--;
> > + __scsi_done(cmd);
> > +}
> > +
> > /*
> > * Kill a request for a dead device
> > */
> > @@ -1527,8 +1543,16 @@ static void scsi_request_fn(struct request_queue *q)
> > * accept it.
> > */
> > req = elv_next_request(q);
> > - if (!req || !scsi_dev_queue_ready(q, sdev))
> > + if (!req)
> > + break;
> > +
> > + if (!scsi_dev_queue_ready(q, sdev)) {
> > + if (req->cmd_flags & REQ_FAILFAST) {
> > + scsi_kill_request(req, q);
> > + continue;
> > + }
> > break;
> > + }
> >
> > if (unlikely(!scsi_device_online(sdev))) {
> > sdev_printk(KERN_ERR, sdev,
> > @@ -1609,8 +1633,12 @@ static void scsi_request_fn(struct request_queue *q)
> > * later time.
> > */
> > spin_lock_irq(q->queue_lock);
> > - blk_requeue_request(q, req);
> > - sdev->device_busy--;
> > + if (unlikely(req->cmd_flags & REQ_FAILFAST))
> > + __scsi_kill_request(req);
> > + else {
> > + blk_requeue_request(q, req);
> > + sdev->device_busy--;
> > + }
> > if(sdev->device_busy == 0)
> > blk_plug_device(q);
> > out:
> Yeah, sorry. That patch was bad. Please use the attached one instead.
> Andrew, can you replace them?

Instead? It won't apply. And it doesn't help on top of git-scsi.
It helps if 3 hunks involving __scsi_kill_request() are ducked.

> --- a/drivers/scsi/scsi_lib.c
> +++ b/drivers/scsi/scsi_lib.c
> @@ -1284,13 +1284,15 @@ int scsi_prep_state_check(struct scsi_device *sdev, struct request *req)
> /*
> * If the devices is blocked we defer normal commands.
> */
> - if (!(req->cmd_flags & REQ_PREEMPT))
> - ret = BLKPREP_DEFER;
> - /*
> - * Return failfast requests immediately
> - */
> - if (req->cmd_flags & REQ_FAILFAST)
> - ret = BLKPREP_KILL;
> + if (!(req->cmd_flags & REQ_PREEMPT)) {
> + /*
> + * Return failfast requests immediately
> + */
> + if (req->cmd_flags & REQ_FAILFAST)
> + ret = BLKPREP_KILL;
> + else
> + ret = BLKPREP_DEFER;
> + }
> break;
> default:
> /*