All of lore.kernel.org
 help / color / mirror / Atom feed
From: Albert Lee <albertcc@tw.ibm.com>
To: Jeff Garzik <jgarzik@pobox.com>
Cc: Linux IDE <linux-ide@vger.kernel.org>,
	Doug Maxey <dwm@maxeymade.com>,
	Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>,
	Tejun Heo <htejun@gmail.com>
Subject: Re: [PATCH 0/2] libata: ata_pio_task() accessing 'ap->pio_task_state' fix
Date: Wed, 07 Sep 2005 18:03:03 +0800	[thread overview]
Message-ID: <431EBAD7.40801@tw.ibm.com> (raw)
In-Reply-To: <431E7D76.60003@pobox.com>

[-- Attachment #1: Type: text/plain, Size: 2252 bytes --]

Jeff,

> Albert Lee wrote:
>
>> Jeff,
>>
>> During PIO, after calling ata_poll_qc_complete(), the next command 
>> might be
>> running and the value of 'ap->pio_task_state' might have been changed.
>> Accessing 'ap->pio_task_state' is not safe at this point.
>>
>> Ex.
>> qc 1 completed. queuing a final task with ap->pio_task_state == 
>> PIO_ST_IDLE.
>> qc 2 started, queuing a new task with ap->pio_task_state set to PIO_ST.
>> qc 1 read ap->pio_task_state as PIO_ST; not PIO_ST_IDLE as expected.
>> => 2 qc running in the workqueue with pio_task_state PIO_ST.
>>
>> Changes:
>>  1/2: Modify ata_pio_complete() and ata_pio_block() to return
>>       whether qc has been completed.
>>
>>  2/2: Modify ata_pio_task() to check the return value. Only queue 
>> next step and
>>        access 'ap->pio_task_state' if the command is not completed.
>
>
> I would prefer something more like the attached patch.  This patch 
> does two things:
> * eliminate needless queueing
> * don't race with qc-complete in ata_pio_complete()

The patch looks good and clearer. :)

Only one minor addition for your review:

* ata_pio_block() changed to go to PIO_ST_LAST state, instead of
   going to PIO_ST_IDLE state directly and calling ata_poll_qc_complete().

i.e.
@@ -2845,9 +2852,7 @@
     if (is_atapi_taskfile(&qc->tf)) {
         /* no more data to transfer or unsupported ATAPI command */
         if ((status & ATA_DRQ) == 0) {
-            ap->pio_task_state = PIO_ST_IDLE;
-
-            ata_poll_qc_complete(qc, status);
+            ap->pio_task_state = PIO_ST_LAST;
             return;
         }

This is needed since ata_pio_block() might complete the qc.
This can also make the pio polling code go through the 
ata_pio_complete(), making the state transition explicit.

Attached please find the revised patch for your review.
(Patched for 2.6.13  80ac2912f846c01d702774bb6aa7100ec71e88b9).

>
> This patch is COMPLETELY UNTESTED.  Please use the attached as a base, 
> to replace the patch series you have submitted.  I won't check it in, 
> as I would like to hear feedback and get some review.
>

Tested ok on x86 PC. Will test on the big machines later.

Albert

(Revision based on Jeff's patch)
Signed-off-by: Albert Lee <albertcc@tw.ibm.com>




[-- Attachment #2: pio_poll.diff --]
[-- Type: text/plain, Size: 2055 bytes --]

--- linux/drivers/scsi/libata-core.c.ori	2005-09-02 17:59:15.000000000 +0800
+++ pio_poll/drivers/scsi/libata-core.c	2005-09-07 16:18:00.000000000 +0800
@@ -2461,9 +2461,12 @@
  *
  *	LOCKING:
  *	None.  (executing in kernel thread context)
+ *
+ *	RETURNS:
+ *	Non-zero if qc completed, zero otherwise.
  */
 
-static void ata_pio_complete (struct ata_port *ap)
+static int ata_pio_complete (struct ata_port *ap)
 {
 	struct ata_queued_cmd *qc;
 	u8 drv_stat;
@@ -2482,14 +2485,14 @@
 		if (drv_stat & (ATA_BUSY | ATA_DRQ)) {
 			ap->pio_task_state = PIO_ST_LAST_POLL;
 			ap->pio_task_timeout = jiffies + ATA_TMOUT_PIO;
-			return;
+			return 0;
 		}
 	}
 
 	drv_stat = ata_wait_idle(ap);
 	if (!ata_ok(drv_stat)) {
 		ap->pio_task_state = PIO_ST_ERR;
-		return;
+		return 0;
 	}
 
 	qc = ata_qc_from_tag(ap, ap->active_tag);
@@ -2498,6 +2501,10 @@
 	ap->pio_task_state = PIO_ST_IDLE;
 
 	ata_poll_qc_complete(qc, drv_stat);
+
+	/* another command may start at this point */
+
+	return 1;
 }
 
 
@@ -2845,9 +2852,7 @@
 	if (is_atapi_taskfile(&qc->tf)) {
 		/* no more data to transfer or unsupported ATAPI command */
 		if ((status & ATA_DRQ) == 0) {
-			ap->pio_task_state = PIO_ST_IDLE;
-
-			ata_poll_qc_complete(qc, status);
+			ap->pio_task_state = PIO_ST_LAST;
 			return;
 		}
 
@@ -2883,7 +2888,12 @@
 static void ata_pio_task(void *_data)
 {
 	struct ata_port *ap = _data;
-	unsigned long timeout = 0;
+	unsigned long timeout;
+	int qc_completed;
+
+fsm_start:
+	timeout = 0;
+	qc_completed = 0;
 
 	switch (ap->pio_task_state) {
 	case PIO_ST_IDLE:
@@ -2894,7 +2904,7 @@
 		break;
 
 	case PIO_ST_LAST:
-		ata_pio_complete(ap);
+		qc_completed = ata_pio_complete(ap);
 		break;
 
 	case PIO_ST_POLL:
@@ -2909,10 +2919,9 @@
 	}
 
 	if (timeout)
-		queue_delayed_work(ata_wq, &ap->pio_task,
-				   timeout);
-	else
-		queue_work(ata_wq, &ap->pio_task);
+		queue_delayed_work(ata_wq, &ap->pio_task, timeout);
+	else if (likely(!qc_completed))
+		goto fsm_start;
 }
 
 static void atapi_request_sense(struct ata_port *ap, struct ata_device *dev,

  reply	other threads:[~2005-09-07 10:03 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-09-02 15:48 [PATCH 0/2] libata: ata_pio_task() accessing 'ap->pio_task_state' fix Albert Lee
2005-09-02 15:53 ` [PATCH 1/2] libata: ata_pio_complete() and ata_pio_block() return value Albert Lee
2005-09-02 15:55 ` [PATCH 2/2] libata: ata_pio_task() fix Albert Lee
2005-09-07  5:41 ` [PATCH 0/2] libata: ata_pio_task() accessing 'ap->pio_task_state' fix Jeff Garzik
2005-09-07 10:03   ` Albert Lee [this message]
2005-09-08  0:43     ` Jeff Garzik
2005-09-08  6:25       ` Albert Lee

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=431EBAD7.40801@tw.ibm.com \
    --to=albertcc@tw.ibm.com \
    --cc=bzolnier@gmail.com \
    --cc=dwm@maxeymade.com \
    --cc=htejun@gmail.com \
    --cc=jgarzik@pobox.com \
    --cc=linux-ide@vger.kernel.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.