linux-ide.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Albert Lee <albertcc@tw.ibm.com>
To: Jeff Garzik <jgarzik@pobox.com>
Cc: "Ralf Müller" <ralf@bj-ig.de>, "Doug Maxey" <dwm@maxeymade.com>,
	"Linux IDE" <linux-ide@vger.kernel.org>
Subject: [PATCH/RFC] libata-dev:  update timer for PIO polling - revised
Date: Fri, 20 Jan 2006 22:19:33 +0800	[thread overview]
Message-ID: <43D0F175.7010206@tw.ibm.com> (raw)
In-Reply-To: <43CD9130.4000600@pobox.com>

Jeff,

Revised per your advice to use the eh_timed_out() handler.

Description:
  In the bug reported by Ralf Müller:
(http://marc.theaimsgroup.com/?l=linux-ide&m=113629906809278&w=2)

When the scsi command times out, the qc is completed by the time
out handler. This might cause null pointer dereference if
the qc is running in the PIO polling thread.

Changes:
  Add ata_scsi_timed_out() to libata-scsi.
  If the qc times out when running in PIO mode, EH_RESET_TIMER is returned.
  Otherwise, EH_NOT_HANDLED is returned and the eh_strategy_handler()
  is triggered as before.

(Will add ata_scsi_timed_out() to LLDs later if this is ok.)

Patch against the libata-dev irq-pio branch 
(000080c3499cd5037e60c08a8053efb9e48aa9c0).

For your review, thanks.

Albert
Signed-off-by: Albert Lee <albertcc@tw.ibm.com>

=====

--- irq-pio/include/linux/libata.h	2006-01-20 10:35:11.000000000 +0800
+++ eh_timed_out/include/linux/libata.h	2006-01-20 10:48:29.000000000 +0800
@@ -449,6 +449,7 @@ extern void ata_host_set_remove(struct a
 extern int ata_scsi_detect(struct scsi_host_template *sht);
 extern int ata_scsi_ioctl(struct scsi_device *dev, int cmd, void __user *arg);
 extern int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *));
+extern enum scsi_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *);
 extern int ata_scsi_error(struct Scsi_Host *host);
 extern int ata_scsi_release(struct Scsi_Host *host);
 extern unsigned int ata_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc);
--- irq-pio/drivers/scsi/libata-scsi.c	2006-01-20 10:35:05.000000000 +0800
+++ eh_timed_out/drivers/scsi/libata-scsi.c	2006-01-20 22:13:14.000000000 +0800
@@ -717,6 +717,59 @@ int ata_scsi_slave_config(struct scsi_de
 }
 
 /**
+ *	ata_scsi_timed_out - SCSI layer time out handler callback
+ *	@cmd: SCSI cmd on which time out occurred
+ *
+ *	Handles SCSI-layer-thrown time out events.
+ *
+ *	RETURNS:
+ *	EH_HANDLED if qc was completed
+ *	EH_RESET_TIMER for polling case
+ *	EH_NOT_HANDLED otherwise.
+ */
+enum scsi_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd)
+{
+	struct scsi_device *scsidev = cmd->device;
+	struct ata_port *ap = (struct ata_port *) &scsidev->host->hostdata[0];
+	struct ata_host_set *host_set = ap->host_set;
+	struct ata_queued_cmd *qc;
+	unsigned long flags;
+	int rc = EH_NOT_HANDLED;
+
+	DPRINTK("ENTER\n");
+	spin_lock_irqsave(&host_set->lock, flags);
+
+	qc = ata_qc_from_tag(ap, ap->active_tag);
+	if (!qc) {
+		/* ata_poll_qc_complete() or ata_interrupt() win the race.
+		 */
+		printk(KERN_ERR "ata%u: timeout without qc\n", ap->id);
+		rc = EH_HANDLED;
+		goto out;
+	}
+
+	/* check if we are handling the right qc */
+	assert(qc->scsicmd == cmd);
+	assert(qc->flags & ATA_QCFLAG_ACTIVE);
+
+	if (qc->tf.flags & ATA_TFLAG_POLLING) {
+		/* The PIO polling thread has its own timeout handling.
+		 * It won't loop forever, even if it takes a long time.
+		 * We can wait the PIO polling thread to finish its work.
+		 * No need to stop the polling thread from the timeout handler.
+		 * Just reset the timer here.
+		 */
+		printk(KERN_WARNING "ata%u: reset scsi timer for PIO polling\n", ap->id);
+		cmd->retries = 0;
+		rc = EH_RESET_TIMER;
+	}
+out:
+	spin_unlock_irqrestore(&host_set->lock, flags);
+	DPRINTK("EXIT rc %d\n", rc);
+	return rc;
+}
+
+/**
  *	ata_scsi_error - SCSI layer error handler callback
  *	@host: SCSI host on which error occurred
  *
--- irq-pio/drivers/scsi/libata-core.c	2006-01-20 10:35:05.000000000 +0800
+++ eh_timed_out/drivers/scsi/libata-core.c	2006-01-20 10:48:44.000000000 +0800
@@ -5434,6 +5434,7 @@ EXPORT_SYMBOL_GPL(ata_port_disable);
 EXPORT_SYMBOL_GPL(ata_ratelimit);
 EXPORT_SYMBOL_GPL(ata_scsi_ioctl);
 EXPORT_SYMBOL_GPL(ata_scsi_queuecmd);
+EXPORT_SYMBOL_GPL(ata_scsi_timed_out);
 EXPORT_SYMBOL_GPL(ata_scsi_error);
 EXPORT_SYMBOL_GPL(ata_scsi_slave_config);
 EXPORT_SYMBOL_GPL(ata_scsi_release);




  reply	other threads:[~2006-01-20 14:19 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-01-03 14:32 Kernel Oops with 2.6.15 Ralf Müller
2006-01-04  3:10 ` Albert Lee
2006-01-04  9:29   ` Ralf Müller
2006-01-06  3:41     ` [PATCH/RFC] libata-dev: update timeout for PIO polling Albert Lee
2006-01-18  0:52       ` Jeff Garzik
2006-01-20 14:19         ` Albert Lee [this message]
2006-01-21  1:05           ` [PATCH/RFC] libata-dev: update timer for PIO polling - revised Tejun Heo

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=43D0F175.7010206@tw.ibm.com \
    --to=albertcc@tw.ibm.com \
    --cc=dwm@maxeymade.com \
    --cc=jgarzik@pobox.com \
    --cc=linux-ide@vger.kernel.org \
    --cc=ralf@bj-ig.de \
    /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;
as well as URLs for NNTP newsgroup(s).