All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Snoop SET FEATURES - WRITE CACHE ENABLE/DISABLE command
@ 2006-05-25  9:02 zhao, forrest
  2006-05-27  0:15 ` Jeff Garzik
  0 siblings, 1 reply; 16+ messages in thread
From: zhao, forrest @ 2006-05-25  9:02 UTC (permalink / raw)
  To: jeff, htejun, liml; +Cc: linux-ide

Hi, all

This patch makes libata "Snoop SET FEATURES - WRITE CACHE ENABLE/DISABLE
command" and clean the things up(e.g. revalidate and rescan). 

Here is the processing path:

1 in ata_scsi_qc_complete(), if we find that a "SET FEATURES - WRITE CACHE
ENABLE/DISABLE" command is executed successfully, we schedule the according
port to do revalidation
2 in ata_dev_revalidate(), if we find that the "write cahce enable bit" was
changed, set port flags in order to schedule scsi_rescan_device() later in
ata_scsi_error()
3 in ata_scsi_error(), if ATA_FLAG_SCSI_RESCAN is set for ap->flags, we
queue the ata_scsi_dev_rescan() to work_queue "ata_scsi_wq"
4 at last, scsi_rescan_device() is invoked, so the current state of "write
cahce enable bit" is propogated to SCSI layer.

The patch is against the curretn #upstream. Your comments are welcome.

Thanks,
Forrest

Signed-off-by: Zhao, Forrest <forrest.zhao@intel.com>


---

 drivers/scsi/libata-core.c |   17 +++++++++++++++++
 drivers/scsi/libata-eh.c   |    5 ++++-
 drivers/scsi/libata-scsi.c |   35 ++++++++++++++++++++++++++++++++++-
 drivers/scsi/libata.h      |    2 ++
 include/linux/ata.h        |    3 +++
 include/linux/libata.h     |    4 +++-
 6 files changed, 63 insertions(+), 3 deletions(-)

bc7324f8b2629241df4120743618d5454ea1834a
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index 074a46e..889a15e 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -69,6 +69,8 @@ static void ata_dev_xfermask(struct ata_
 static unsigned int ata_unique_id = 1;
 static struct workqueue_struct *ata_wq;
 
+struct workqueue_struct *ata_scsi_wq;
+
 int atapi_enabled = 1;
 module_param(atapi_enabled, int, 0444);
 MODULE_PARM_DESC(atapi_enabled, "Enable discovery of ATAPI devices (0=off, 1=on)");
@@ -2911,6 +2913,13 @@ int ata_dev_revalidate(struct ata_device
 		goto fail;
 	}
 
+	/* if the write cahce enable bit is changed, set port flags
+	 * in order to schedule scsi_rescan_device() later in
+	 * ata_scsi_error()
+	 */
+	if ((dev->id[85] & (1 << 5)) != (id[85] & (1 << 5)))
+		dev->ap->flags |= ATA_FLAG_SCSI_RESCAN;
+
 	memcpy(dev->id, id, sizeof(id[0]) * ATA_ID_WORDS);
 
 	/* configure device according to the new ID */
@@ -5160,6 +5169,7 @@ static void ata_host_init(struct ata_por
 	ap->last_ctl = 0xFF;
 
 	INIT_WORK(&ap->port_task, NULL, NULL);
+	INIT_WORK(&ap->scsi_rescan_task, ata_scsi_dev_rescan, ap);
 	INIT_LIST_HEAD(&ap->eh_done_q);
 
 	/* set cable type */
@@ -5565,6 +5575,12 @@ static int __init ata_init(void)
 	if (!ata_wq)
 		return -ENOMEM;
 
+	ata_scsi_wq = create_singlethread_workqueue("ata_scsi");
+	if (!ata_scsi_wq) {
+		destroy_workqueue(ata_wq);
+		return -ENOMEM;
+	}
+
 	printk(KERN_DEBUG "libata version " DRV_VERSION " loaded.\n");
 	return 0;
 }
@@ -5572,6 +5588,7 @@ static int __init ata_init(void)
 static void __exit ata_exit(void)
 {
 	destroy_workqueue(ata_wq);
+	destroy_workqueue(ata_scsi_wq);
 }
 
 module_init(ata_init);
diff --git a/drivers/scsi/libata-eh.c b/drivers/scsi/libata-eh.c
index 71b45ad..241aa49 100644
--- a/drivers/scsi/libata-eh.c
+++ b/drivers/scsi/libata-eh.c
@@ -286,9 +286,12 @@ void ata_scsi_error(struct Scsi_Host *ho
 	/* clean up */
 	spin_lock_irqsave(hs_lock, flags);
 
+	if (ap->flags & ATA_FLAG_SCSI_RESCAN)
+		queue_work(ata_scsi_wq, &ap->scsi_rescan_task);
+
 	if (ap->flags & ATA_FLAG_RECOVERED)
 		ata_port_printk(ap, KERN_INFO, "EH complete\n");
-	ap->flags &= ~ATA_FLAG_RECOVERED;
+	ap->flags &= ~(ATA_FLAG_RECOVERED | ATA_FLAG_SCSI_RESCAN);
 
 	spin_unlock_irqrestore(hs_lock, flags);
 
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c
index 9e5cb9f..c49b9bd 100644
--- a/drivers/scsi/libata-scsi.c
+++ b/drivers/scsi/libata-scsi.c
@@ -1269,6 +1269,18 @@ static void ata_scsi_qc_complete(struct 
 	u8 *cdb = cmd->cmnd;
  	int need_sense = (qc->err_mask != 0);
 
+	/* We snoop the SET_FEATURES - Write Cache ON/OFF command, and
+	 * schedule EH_REVALIDATE operation to update the IDENTIFY DEVICE
+	 * cache
+	 */
+	if (((cdb[0] == ATA_16) || (cdb[0] == ATA_12)) &&
+	    (!(cdb[2] & 0x20)) && (qc->tf.command == ATA_CMD_SET_FEATURES) &&
+	    ((qc->tf.feature == SETFEATURES_WC_ON) ||
+	     (qc->tf.feature == SETFEATURES_WC_OFF))) {
+		qc->ap->eh_info.action = ATA_EH_REVALIDATE;
+		ata_port_schedule_eh(qc->ap);
+	}
+
 	/* For ATA pass thru (SAT) commands, generate a sense block if
 	 * user mandated it or if there's an error.  Note that if we
 	 * generate because the user forced us to, a check condition
@@ -2744,9 +2756,30 @@ void ata_scsi_scan_host(struct ata_port 
 		return;
 
 	for (i = 0; i < ATA_MAX_DEVICES; i++) {
+		struct scsi_device *sdev;
+		dev = &ap->device[i];
+
+		if (!ata_dev_enabled(dev) || dev->sdev)
+			continue;
+		sdev = __scsi_add_device(ap->host, 0, i, 0, NULL);
+		if(!IS_ERR(sdev)){
+			dev->sdev = sdev;
+			scsi_device_put(sdev);
+		}
+	}
+}
+
+void ata_scsi_dev_rescan(void *data)
+{
+	struct ata_port *ap = data;
+	struct ata_device *dev;
+	unsigned int i;
+
+	for (i = 0; i < ATA_MAX_DEVICES; i++) {
 		dev = &ap->device[i];
 
 		if (ata_dev_enabled(dev))
-			scsi_scan_target(&ap->host->shost_gendev, 0, i, 0, 0);
+			scsi_rescan_device(&(dev->sdev->sdev_gendev));
 	}
 }
+
diff --git a/drivers/scsi/libata.h b/drivers/scsi/libata.h
index b76ad7d..352d332 100644
--- a/drivers/scsi/libata.h
+++ b/drivers/scsi/libata.h
@@ -39,6 +39,7 @@ struct ata_scsi_args {
 };
 
 /* libata-core.c */
+extern struct workqueue_struct *ata_scsi_wq;
 extern int atapi_enabled;
 extern int atapi_dmadir;
 extern int libata_fua;
@@ -99,6 +100,7 @@ extern void ata_scsi_rbuf_fill(struct at
                         unsigned int (*actor) (struct ata_scsi_args *args,
                                            u8 *rbuf, unsigned int buflen));
 extern void ata_schedule_scsi_eh(struct Scsi_Host *shost);
+extern void ata_scsi_dev_rescan(void *data);
 
 /* libata-eh.c */
 extern enum scsi_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd);
diff --git a/include/linux/ata.h b/include/linux/ata.h
index c494e1c..3671af8 100644
--- a/include/linux/ata.h
+++ b/include/linux/ata.h
@@ -181,6 +181,9 @@ enum {
 	XFER_PIO_0		= 0x08,
 	XFER_PIO_SLOW		= 0x00,
 
+	SETFEATURES_WC_ON	= 0x02, /* Enable write cache */
+	SETFEATURES_WC_OFF	= 0x82, /* Disable write cache */
+
 	/* ATAPI stuff */
 	ATAPI_PKT_DMA		= (1 << 0),
 	ATAPI_DMADIR		= (1 << 2),	/* ATAPI data dir:
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 9c60b4a..687564d 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -159,6 +159,7 @@ enum {
 	ATA_FLAG_EH_PENDING	= (1 << 16), /* EH pending */
 	ATA_FLAG_FROZEN		= (1 << 17), /* port is frozen */
 	ATA_FLAG_RECOVERED	= (1 << 18), /* recovery action performed */
+	ATA_FLAG_SCSI_RESCAN	= (1 << 19), /* scsi device rescan is scheduled */
 
 	ATA_FLAG_DISABLED	= (1 << 22), /* port is disabled, ignore it */
 	ATA_FLAG_SUSPENDED	= (1 << 23), /* port is suspended (power) */
@@ -402,6 +403,7 @@ struct ata_device {
 	unsigned long		flags;		/* ATA_DFLAG_xxx */
 	unsigned int		class;		/* ATA_DEV_xxx */
 	unsigned int		devno;		/* 0 or 1 */
+	struct scsi_device	*sdev;		/* attached SCSI device */
 	u16			id[ATA_ID_WORDS]; /* IDENTIFY xxx DEVICE data */
 	u8			pio_mode;
 	u8			dma_mode;
@@ -484,7 +486,7 @@ struct ata_port {
 	struct ata_host_set	*host_set;
 	struct device 		*dev;
 
-	struct work_struct	port_task;
+	struct work_struct	port_task, scsi_rescan_task;
 
 	unsigned int		hsm_task_state;
 
-- 
1.2.6


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH] Snoop SET FEATURES - WRITE CACHE ENABLE/DISABLE command
  2006-05-25  9:02 [PATCH] Snoop SET FEATURES - WRITE CACHE ENABLE/DISABLE command zhao, forrest
@ 2006-05-27  0:15 ` Jeff Garzik
  2006-05-29  6:35   ` zhao, forrest
  2006-05-29  9:08   ` Tejun Heo
  0 siblings, 2 replies; 16+ messages in thread
From: Jeff Garzik @ 2006-05-27  0:15 UTC (permalink / raw)
  To: zhao, forrest, htejun; +Cc: liml, linux-ide

zhao, forrest wrote:
> Hi, all
> 
> This patch makes libata "Snoop SET FEATURES - WRITE CACHE ENABLE/DISABLE
> command" and clean the things up(e.g. revalidate and rescan). 
> 
> Here is the processing path:
> 
> 1 in ata_scsi_qc_complete(), if we find that a "SET FEATURES - WRITE CACHE
> ENABLE/DISABLE" command is executed successfully, we schedule the according
> port to do revalidation
> 2 in ata_dev_revalidate(), if we find that the "write cahce enable bit" was
> changed, set port flags in order to schedule scsi_rescan_device() later in
> ata_scsi_error()
> 3 in ata_scsi_error(), if ATA_FLAG_SCSI_RESCAN is set for ap->flags, we
> queue the ata_scsi_dev_rescan() to work_queue "ata_scsi_wq"
> 4 at last, scsi_rescan_device() is invoked, so the current state of "write
> cahce enable bit" is propogated to SCSI layer.

I agree with the concept, and agree that the SCSI layer must be notified 
when the ATA write cache type changes.  However, I NAK the patch for the 
following reasons:

1) Tejun's revalidate should trigger scsi_rescan_device(), as your patch 
indicates.  But that's pretty much all that needs to be done.

2) Thus, a new bit (ATA_FLAG_SCSI_RESCAN) and a new workqueue are 
unnecessary.

3) While the following test is correct,
+	if ((dev->id[85] & (1 << 5)) != (id[85] & (1 << 5)))
+		dev->ap->flags |= ATA_FLAG_SCSI_RESCAN;

there is no pressing need to avoid unnecessary rescans, during revalidation.

4) Using [__]scsi_add_device() is a regression from using scsi_scan_target()


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH] Snoop SET FEATURES - WRITE CACHE ENABLE/DISABLE command
  2006-05-27  0:15 ` Jeff Garzik
@ 2006-05-29  6:35   ` zhao, forrest
  2006-05-29 11:29     ` Mark Lord
  2006-05-29  9:08   ` Tejun Heo
  1 sibling, 1 reply; 16+ messages in thread
From: zhao, forrest @ 2006-05-29  6:35 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: htejun, liml, linux-ide

On Fri, 2006-05-26 at 20:15 -0400, Jeff Garzik wrote:
> I agree with the concept, and agree that the SCSI layer must be notified 
> when the ATA write cache type changes.  However, I NAK the patch for the 
> following reasons:
> 
> 1) Tejun's revalidate should trigger scsi_rescan_device(), as your patch 
> indicates.  But that's pretty much all that needs to be done.
> 
> 2) Thus, a new bit (ATA_FLAG_SCSI_RESCAN) and a new workqueue are 
> unnecessary.

Doing scsi_rescan_device() in SCSI EH thread caused my machine with 1
logical CPU to hang(it stopped responding, user can't login locally or
remotely, and it can only respond to "ping".)
So I think scsi_rescan_device() is prohibited from being invoked in SCSI
EH thread. This is the reason why I introduced another work_queue to do
scsi_rescan_device().

The following patch is again current #upstream and can reproduce the
problem.

After the kernel with this patch boots up, "hdparm -W 0 /dev/sd*" can
trigger the system to hang.

Thanks,
Forrest

diff --git a/drivers/scsi/libata-eh.c b/drivers/scsi/libata-eh.c
index 71b45ad..d833b36 100644
--- a/drivers/scsi/libata-eh.c
+++ b/drivers/scsi/libata-eh.c
@@ -1356,6 +1356,8 @@ static int ata_eh_revalidate(struct ata_
 			if (rc)
 				break;
 
+			scsi_rescan_device(&(dev->sdev->sdev_gendev));
+
 			ehc->i.action &= ~ATA_EH_REVALIDATE;
 		}
 	}
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c
index 9e5cb9f..0838e9b 100644
--- a/drivers/scsi/libata-scsi.c
+++ b/drivers/scsi/libata-scsi.c
@@ -1269,6 +1269,19 @@ static void ata_scsi_qc_complete(struct 
 	u8 *cdb = cmd->cmnd;
  	int need_sense = (qc->err_mask != 0);
 
+	/* We snoop the SET_FEATURES - Write Cache ON/OFF command, and
+	 * schedule EH_REVALIDATE operation to update the IDENTIFY DEVICE
+	 * cache
+	 */
+	if (((cdb[0] == ATA_16) || (cdb[0] == ATA_12)) &&
+	    (!(cdb[2] & 0x20)) && (qc->tf.command == ATA_CMD_SET_FEATURES) &&
+	    ((qc->tf.feature == SETFEATURES_WC_ON) ||
+	     (qc->tf.feature == SETFEATURES_WC_OFF))) {
+		qc->ap->eh_info.action = ATA_EH_REVALIDATE;
+		ata_port_schedule_eh(qc->ap);
+	}
+
+
 	/* For ATA pass thru (SAT) commands, generate a sense block if
 	 * user mandated it or if there's an error.  Note that if we
 	 * generate because the user forced us to, a check condition
@@ -2744,9 +2757,17 @@ void ata_scsi_scan_host(struct ata_port 
 		return;
 
 	for (i = 0; i < ATA_MAX_DEVICES; i++) {
+		struct scsi_device *sdev;
 		dev = &ap->device[i];
 
-		if (ata_dev_enabled(dev))
-			scsi_scan_target(&ap->host->shost_gendev, 0, i, 0, 0);
+		if (!ata_dev_enabled(dev) || dev->sdev)
+			continue;
+		sdev = __scsi_add_device(ap->host, 0, i, 0, NULL);
+		if(!IS_ERR(sdev)){
+			dev->sdev = sdev;
+			scsi_device_put(sdev);
+		}
 	}
 }
+
+
diff --git a/include/linux/ata.h b/include/linux/ata.h
index c494e1c..3671af8 100644
--- a/include/linux/ata.h
+++ b/include/linux/ata.h
@@ -181,6 +181,9 @@ enum {
 	XFER_PIO_0		= 0x08,
 	XFER_PIO_SLOW		= 0x00,
 
+	SETFEATURES_WC_ON	= 0x02, /* Enable write cache */
+	SETFEATURES_WC_OFF	= 0x82, /* Disable write cache */
+
 	/* ATAPI stuff */
 	ATAPI_PKT_DMA		= (1 << 0),
 	ATAPI_DMADIR		= (1 << 2),	/* ATAPI data dir:
diff --git a/include/linux/libata.h b/include/linux/libata.h
index b0ee1c1..79ea9a5 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -402,6 +402,7 @@ struct ata_device {
 	unsigned long		flags;		/* ATA_DFLAG_xxx */
 	unsigned int		class;		/* ATA_DEV_xxx */
 	unsigned int		devno;		/* 0 or 1 */
+	struct scsi_device	*sdev;
 	u16			id[ATA_ID_WORDS]; /* IDENTIFY xxx DEVICE data */
 	u8			pio_mode;
 	u8			dma_mode;

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH] Snoop SET FEATURES - WRITE CACHE ENABLE/DISABLE command
  2006-05-27  0:15 ` Jeff Garzik
  2006-05-29  6:35   ` zhao, forrest
@ 2006-05-29  9:08   ` Tejun Heo
  2006-05-29  9:18     ` zhao, forrest
                       ` (2 more replies)
  1 sibling, 3 replies; 16+ messages in thread
From: Tejun Heo @ 2006-05-29  9:08 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: zhao, forrest, liml, linux-ide

Jeff Garzik wrote:
> zhao, forrest wrote:
>> Hi, all
>>
>> This patch makes libata "Snoop SET FEATURES - WRITE CACHE ENABLE/DISABLE
>> command" and clean the things up(e.g. revalidate and rescan).
>> Here is the processing path:
>>
>> 1 in ata_scsi_qc_complete(), if we find that a "SET FEATURES - WRITE 
>> CACHE
>> ENABLE/DISABLE" command is executed successfully, we schedule the 
>> according
>> port to do revalidation
>> 2 in ata_dev_revalidate(), if we find that the "write cahce enable 
>> bit" was
>> changed, set port flags in order to schedule scsi_rescan_device() 
>> later in
>> ata_scsi_error()
>> 3 in ata_scsi_error(), if ATA_FLAG_SCSI_RESCAN is set for ap->flags, we
>> queue the ata_scsi_dev_rescan() to work_queue "ata_scsi_wq"
>> 4 at last, scsi_rescan_device() is invoked, so the current state of 
>> "write
>> cahce enable bit" is propogated to SCSI layer.
> 
> I agree with the concept, and agree that the SCSI layer must be notified 
> when the ATA write cache type changes.  However, I NAK the patch for the 
> following reasons:
> 
> 1) Tejun's revalidate should trigger scsi_rescan_device(), as your patch 
> indicates.  But that's pretty much all that needs to be done.
> 
> 2) Thus, a new bit (ATA_FLAG_SCSI_RESCAN) and a new workqueue are 
> unnecessary.

SCSI rescan is done by issuing commands using scsi_execute_req().  The 
commands are supposed to be processed via normal SCSI command execution 
path which is blocked during EH is in progress, so we need to rescan in 
separate context.

> 3) While the following test is correct,
> +    if ((dev->id[85] & (1 << 5)) != (id[85] & (1 << 5)))
> +        dev->ap->flags |= ATA_FLAG_SCSI_RESCAN;
> 
> there is no pressing need to avoid unnecessary rescans, during 
> revalidation.

Agreed.  Just rescan unconditionally.

> 4) Using [__]scsi_add_device() is a regression from using 
> scsi_scan_target()

I think it's taken from the hotplug patch store-attached-SCSI-device[1]. 
  Using [__]scsi_add_device() seems to be the only way to reliably 
obtain the attached sdev.

More notes...

* I've renamed ata_hotplug_wq to ata_scsi_wq in hotplug patches.  I 
think rescan can use this wq instead of creating its own.

* When snooping for SETFEATURES in ata_scsi_qc_complete(), why check 
cdb[0] for ATA_16/12?  Isn't simply checking tf.command enough?

* There's a race window between ATA revalidation and SCSI rescan.  We 
can plug this hole by deferring commands till rescan is complete.  But I 
doubt it would be worth the trouble.

-- 
tejun

[1] http://article.gmane.org/gmane.linux.ide/10898

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH] Snoop SET FEATURES - WRITE CACHE ENABLE/DISABLE command
  2006-05-29  9:08   ` Tejun Heo
@ 2006-05-29  9:18     ` zhao, forrest
  2006-05-29  9:46       ` Tejun Heo
  2006-05-29  9:20     ` Jeff Garzik
  2006-05-30  4:41     ` Jeff Garzik
  2 siblings, 1 reply; 16+ messages in thread
From: zhao, forrest @ 2006-05-29  9:18 UTC (permalink / raw)
  To: Tejun Heo; +Cc: Jeff Garzik, liml, linux-ide

On Mon, 2006-05-29 at 18:08 +0900, Tejun Heo wrote:

> > 
> > 1) Tejun's revalidate should trigger scsi_rescan_device(), as your patch 
> > indicates.  But that's pretty much all that needs to be done.
> > 
> > 2) Thus, a new bit (ATA_FLAG_SCSI_RESCAN) and a new workqueue are 
> > unnecessary.
> 
> SCSI rescan is done by issuing commands using scsi_execute_req().  The 
> commands are supposed to be processed via normal SCSI command execution 
> path which is blocked during EH is in progress, so we need to rescan in 
> separate context.
Thank you for giving the reason why my machine hanged when
scsi_rescan_device() is invoked in SCSI EH thread :)
> 
> * I've renamed ata_hotplug_wq to ata_scsi_wq in hotplug patches.  I 
> think rescan can use this wq instead of creating its own.
Yes, ata_scsi_wq will do the work, which can't be done in SCSI EH thread.

> * When snooping for SETFEATURES in ata_scsi_qc_complete(), why check 
> cdb[0] for ATA_16/12?  Isn't simply checking tf.command enough?
Oh, checking cdb[0] for ATA_16/12 is unnecessary since the command id is
unique.

> * There's a race window between ATA revalidation and SCSI rescan.  We 
> can plug this hole by deferring commands till rescan is complete.  But I 
> doubt it would be worth the trouble.
> 
This is really a problem. But the race condition is not so critical that
we need to bother to do some sync between libata and SCSI layer, right?

Thanks,
Forrest

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH] Snoop SET FEATURES - WRITE CACHE ENABLE/DISABLE command
  2006-05-29  9:08   ` Tejun Heo
  2006-05-29  9:18     ` zhao, forrest
@ 2006-05-29  9:20     ` Jeff Garzik
  2006-05-29  9:43       ` Tejun Heo
  2006-05-30  4:41     ` Jeff Garzik
  2 siblings, 1 reply; 16+ messages in thread
From: Jeff Garzik @ 2006-05-29  9:20 UTC (permalink / raw)
  To: Tejun Heo; +Cc: zhao, forrest, liml, linux-ide

Tejun Heo wrote:
> Jeff Garzik wrote:
>> 4) Using [__]scsi_add_device() is a regression from using 
>> scsi_scan_target()
> 
> I think it's taken from the hotplug patch store-attached-SCSI-device[1]. 
>  Using [__]scsi_add_device() seems to be the only way to reliably obtain 
> the attached sdev.


We want to continue to use scsi_scan_target(), because that's the 
preferred model.  In SCSI-land, the target is what receives RPC calls 
(ATA commands, for us), which are then dispatched internally to one of 
$N logical units (LU) according to the logical unit number (LUN).

In libata, of course, there is only one logical unit attached to the 
target, LUN 0.

Regardless, using [__]scsi_add_device() is a regression, because libata 
handles the transport layer completely -- and importantly -- handles all 
addressing.  scsi_add_device() is specifically for H/C/I/L, i.e. SPI 
(parallel SCSI) addressing.

Eventually SCSI will reach a point where HCIL is not the only addressing 
method.  SAS disks, for example, are addressed via a LUN's WWN.  SCSI 
fibre channel addresses LUNs via WWN as well.  Once SCSI core does not 
exclusively use HCIL addressing, libata will reap the benefits of using 
the proper scsi_target model.

	Jeff




^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH] Snoop SET FEATURES - WRITE CACHE ENABLE/DISABLE command
  2006-05-29  9:20     ` Jeff Garzik
@ 2006-05-29  9:43       ` Tejun Heo
  2006-05-30  3:57         ` Jeff Garzik
  0 siblings, 1 reply; 16+ messages in thread
From: Tejun Heo @ 2006-05-29  9:43 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: zhao, forrest, liml, linux-ide

Jeff Garzik wrote:
> Tejun Heo wrote:
>> Jeff Garzik wrote:
>>> 4) Using [__]scsi_add_device() is a regression from using 
>>> scsi_scan_target()
>>
>> I think it's taken from the hotplug patch 
>> store-attached-SCSI-device[1].  Using [__]scsi_add_device() seems to 
>> be the only way to reliably obtain the attached sdev.
> 
> 
> We want to continue to use scsi_scan_target(), because that's the 
> preferred model.  In SCSI-land, the target is what receives RPC calls 
> (ATA commands, for us), which are then dispatched internally to one of 
> $N logical units (LU) according to the logical unit number (LUN).
> 
> In libata, of course, there is only one logical unit attached to the 
> target, LUN 0.
> 
> Regardless, using [__]scsi_add_device() is a regression, because libata 
> handles the transport layer completely -- and importantly -- handles all 
> addressing.  scsi_add_device() is specifically for H/C/I/L, i.e. SPI 
> (parallel SCSI) addressing.
> 
> Eventually SCSI will reach a point where HCIL is not the only addressing 
> method.  SAS disks, for example, are addressed via a LUN's WWN.  SCSI 
> fibre channel addresses LUNs via WWN as well.  Once SCSI core does not 
> exclusively use HCIL addressing, libata will reap the benefits of using 
> the proper scsi_target model.

I fully agree with everything you said, but we're faced with a real 
problem here.  libata needs to know the current attached sdev for 
hotplug and rescan; however, there's no way to determine the current 
sdev after it's already added.

scsi_device_lookup*() functions don't discriminate between dead and live 
devices and ends up operating on the first device it stumbles upon (the 
dead one if it's still hanging around).  Storing dev->sdev was a way to 
get around the limitation.  If a SCSI function which looks up the live 
device is implemented, we don't need to store dev->sdev at all.  IMHO, 
the current implementation can be left as it is until such interface is 
implemented.

Thanks.

-- 
tejun

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH] Snoop SET FEATURES - WRITE CACHE ENABLE/DISABLE command
  2006-05-29  9:18     ` zhao, forrest
@ 2006-05-29  9:46       ` Tejun Heo
  0 siblings, 0 replies; 16+ messages in thread
From: Tejun Heo @ 2006-05-29  9:46 UTC (permalink / raw)
  To: zhao, forrest; +Cc: Jeff Garzik, liml, linux-ide

zhao, forrest wrote:
>> * There's a race window between ATA revalidation and SCSI rescan.  We 
>> can plug this hole by deferring commands till rescan is complete.  But I 
>> doubt it would be worth the trouble.
>>
> This is really a problem. But the race condition is not so critical that
> we need to bother to do some sync between libata and SCSI layer, right?

I guess/hope so.  The only thing which can make any difference seems to
be the cache type setting.  I don't think small race window would cause
too much trouble there.

-- 
tejun

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH] Snoop SET FEATURES - WRITE CACHE ENABLE/DISABLE command
  2006-05-29  6:35   ` zhao, forrest
@ 2006-05-29 11:29     ` Mark Lord
  0 siblings, 0 replies; 16+ messages in thread
From: Mark Lord @ 2006-05-29 11:29 UTC (permalink / raw)
  To: zhao, forrest; +Cc: Jeff Garzik, htejun, linux-ide

zhao, forrest wrote:
>
> Doing scsi_rescan_device() in SCSI EH thread caused my machine with 1
> logical CPU to hang(it stopped responding, user can't login locally or
> remotely, and it can only respond to "ping".)
>
> So I think scsi_rescan_device() is prohibited from being invoked in SCSI
> EH thread.

Yup, that's how it works, as I also discovered when the qstor.c driver
became the first user of the "new" SCSI EH logic two years ago.

Cheers

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH] Snoop SET FEATURES - WRITE CACHE ENABLE/DISABLE command
  2006-05-29  9:43       ` Tejun Heo
@ 2006-05-30  3:57         ` Jeff Garzik
  0 siblings, 0 replies; 16+ messages in thread
From: Jeff Garzik @ 2006-05-30  3:57 UTC (permalink / raw)
  To: Tejun Heo; +Cc: zhao, forrest, liml, linux-ide

Tejun Heo wrote:
> Jeff Garzik wrote:
>> Tejun Heo wrote:
>>> Jeff Garzik wrote:
>>>> 4) Using [__]scsi_add_device() is a regression from using 
>>>> scsi_scan_target()
>>>
>>> I think it's taken from the hotplug patch 
>>> store-attached-SCSI-device[1].  Using [__]scsi_add_device() seems to 
>>> be the only way to reliably obtain the attached sdev.
>>
>>
>> We want to continue to use scsi_scan_target(), because that's the 
>> preferred model.  In SCSI-land, the target is what receives RPC calls 
>> (ATA commands, for us), which are then dispatched internally to one of 
>> $N logical units (LU) according to the logical unit number (LUN).
>>
>> In libata, of course, there is only one logical unit attached to the 
>> target, LUN 0.
>>
>> Regardless, using [__]scsi_add_device() is a regression, because 
>> libata handles the transport layer completely -- and importantly -- 
>> handles all addressing.  scsi_add_device() is specifically for 
>> H/C/I/L, i.e. SPI (parallel SCSI) addressing.
>>
>> Eventually SCSI will reach a point where HCIL is not the only 
>> addressing method.  SAS disks, for example, are addressed via a LUN's 
>> WWN.  SCSI fibre channel addresses LUNs via WWN as well.  Once SCSI 
>> core does not exclusively use HCIL addressing, libata will reap the 
>> benefits of using the proper scsi_target model.
> 
> I fully agree with everything you said, but we're faced with a real 
> problem here.  libata needs to know the current attached sdev for 
> hotplug and rescan; however, there's no way to determine the current 
> sdev after it's already added.

[looks at the core code again]  That's not the problem.  The real 
problem is that scsi_target hotplug infrastructure is non-existent. 
scsi_transport_fc gives a hint as to how nasty it would be to add such 
code, too.

So, life sucks.  Oh well.  Your solution is therefore the best, under 
present circumstances.  ACK use of [__]scsi_add_device().

	Jeff



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH] Snoop SET FEATURES - WRITE CACHE ENABLE/DISABLE command
  2006-05-29  9:08   ` Tejun Heo
  2006-05-29  9:18     ` zhao, forrest
  2006-05-29  9:20     ` Jeff Garzik
@ 2006-05-30  4:41     ` Jeff Garzik
  2006-05-30  4:50       ` Tejun Heo
  2 siblings, 1 reply; 16+ messages in thread
From: Jeff Garzik @ 2006-05-30  4:41 UTC (permalink / raw)
  To: Tejun Heo; +Cc: zhao, forrest, liml, linux-ide

Tejun Heo wrote:
> * I've renamed ata_hotplug_wq to ata_scsi_wq in hotplug patches.  I 
> think rescan can use this wq instead of creating its own.

I think we will use this workqueue even when SCSI is optional, so 
ata_scsi_wq may not be the best name, long term.  I ACK'd its inclusion 
of course, so not a big deal.


> * When snooping for SETFEATURES in ata_scsi_qc_complete(), why check 
> cdb[0] for ATA_16/12?  Isn't simply checking tf.command enough?

yes


> * There's a race window between ATA revalidation and SCSI rescan.  We 
> can plug this hole by deferring commands till rescan is complete.  But I 
> doubt it would be worth the trouble.

probably, we'll see...  :)

	Jeff



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH] Snoop SET FEATURES - WRITE CACHE ENABLE/DISABLE command
  2006-05-30  4:41     ` Jeff Garzik
@ 2006-05-30  4:50       ` Tejun Heo
  2006-05-30  4:57         ` Jeff Garzik
  0 siblings, 1 reply; 16+ messages in thread
From: Tejun Heo @ 2006-05-30  4:50 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: zhao, forrest, liml, linux-ide

Jeff Garzik wrote:
> Tejun Heo wrote:
>> * I've renamed ata_hotplug_wq to ata_scsi_wq in hotplug patches.  I 
>> think rescan can use this wq instead of creating its own.
> 
> I think we will use this workqueue even when SCSI is optional, so 
> ata_scsi_wq may not be the best name, long term.  I ACK'd its inclusion 
> of course, so not a big deal.

As it seems there will be another round of hotplug patches, I can rename 
it without too much trouble.  My candidates are...

ata_aux_wq
ata_management_wq / ata_mgmt_wq
ata_errands_wq

>> * When snooping for SETFEATURES in ata_scsi_qc_complete(), why check 
>> cdb[0] for ATA_16/12?  Isn't simply checking tf.command enough?
> 
> yes
> 
> 
>> * There's a race window between ATA revalidation and SCSI rescan.  We 
>> can plug this hole by deferring commands till rescan is complete.  But 
>> I doubt it would be worth the trouble.
> 
> probably, we'll see...  :)

Yeap, let's see.  I think this should fix Ric's cache type / barrier 
type problem.

-- 
tejun

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH] Snoop SET FEATURES - WRITE CACHE ENABLE/DISABLE command
  2006-05-30  4:50       ` Tejun Heo
@ 2006-05-30  4:57         ` Jeff Garzik
  2006-05-30  5:10           ` Tejun Heo
  0 siblings, 1 reply; 16+ messages in thread
From: Jeff Garzik @ 2006-05-30  4:57 UTC (permalink / raw)
  To: Tejun Heo; +Cc: zhao, forrest, liml, linux-ide

Tejun Heo wrote:
> Jeff Garzik wrote:
>> Tejun Heo wrote:
>>> * I've renamed ata_hotplug_wq to ata_scsi_wq in hotplug patches.  I 
>>> think rescan can use this wq instead of creating its own.
>>
>> I think we will use this workqueue even when SCSI is optional, so 
>> ata_scsi_wq may not be the best name, long term.  I ACK'd its 
>> inclusion of course, so not a big deal.
> 
> As it seems there will be another round of hotplug patches, I can rename 
> it without too much trouble.  My candidates are...
> 
> ata_aux_wq
> ata_management_wq / ata_mgmt_wq
> ata_errands_wq

Another thing to consider is using the kthread API, ignore workqueues, 
and simply creating "one-shot" threads as needed.

	Jeff




^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH] Snoop SET FEATURES - WRITE CACHE ENABLE/DISABLE command
  2006-05-30  5:10           ` Tejun Heo
@ 2006-05-30  5:08             ` zhao, forrest
  2006-05-30  7:22               ` Tejun Heo
  0 siblings, 1 reply; 16+ messages in thread
From: zhao, forrest @ 2006-05-30  5:08 UTC (permalink / raw)
  To: Tejun Heo; +Cc: Jeff Garzik, liml, linux-ide

On Tue, 2006-05-30 at 14:10 +0900, Tejun Heo wrote:
> Jeff Garzik wrote:
> > Tejun Heo wrote:
> >> Jeff Garzik wrote:
> >>> Tejun Heo wrote:
> >>>> * I've renamed ata_hotplug_wq to ata_scsi_wq in hotplug patches.  I 
> >>>> think rescan can use this wq instead of creating its own.
> >>>
> >>> I think we will use this workqueue even when SCSI is optional, so 
> >>> ata_scsi_wq may not be the best name, long term.  I ACK'd its 
> >>> inclusion of course, so not a big deal.
> >>
> >> As it seems there will be another round of hotplug patches, I can 
> >> rename it without too much trouble.  My candidates are...
> >>
> >> ata_aux_wq
> >> ata_management_wq / ata_mgmt_wq
> >> ata_errands_wq
> > 
> > Another thing to consider is using the kthread API, ignore workqueues, 
> > and simply creating "one-shot" threads as needed.
> 
> It wouldn't work for SCSI hotplug.  It depends on that there is only one 
> thread running the thing, so I think wq is the better choice.  Any 
> suggestion on naming?

ata_misc_wq?
ata_sweep_wq?

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH] Snoop SET FEATURES - WRITE CACHE ENABLE/DISABLE command
  2006-05-30  4:57         ` Jeff Garzik
@ 2006-05-30  5:10           ` Tejun Heo
  2006-05-30  5:08             ` zhao, forrest
  0 siblings, 1 reply; 16+ messages in thread
From: Tejun Heo @ 2006-05-30  5:10 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: zhao, forrest, liml, linux-ide

Jeff Garzik wrote:
> Tejun Heo wrote:
>> Jeff Garzik wrote:
>>> Tejun Heo wrote:
>>>> * I've renamed ata_hotplug_wq to ata_scsi_wq in hotplug patches.  I 
>>>> think rescan can use this wq instead of creating its own.
>>>
>>> I think we will use this workqueue even when SCSI is optional, so 
>>> ata_scsi_wq may not be the best name, long term.  I ACK'd its 
>>> inclusion of course, so not a big deal.
>>
>> As it seems there will be another round of hotplug patches, I can 
>> rename it without too much trouble.  My candidates are...
>>
>> ata_aux_wq
>> ata_management_wq / ata_mgmt_wq
>> ata_errands_wq
> 
> Another thing to consider is using the kthread API, ignore workqueues, 
> and simply creating "one-shot" threads as needed.

It wouldn't work for SCSI hotplug.  It depends on that there is only one 
thread running the thing, so I think wq is the better choice.  Any 
suggestion on naming?

-- 
tejun

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH] Snoop SET FEATURES - WRITE CACHE ENABLE/DISABLE command
  2006-05-30  5:08             ` zhao, forrest
@ 2006-05-30  7:22               ` Tejun Heo
  0 siblings, 0 replies; 16+ messages in thread
From: Tejun Heo @ 2006-05-30  7:22 UTC (permalink / raw)
  To: zhao, forrest; +Cc: Jeff Garzik, liml, linux-ide

zhao, forrest wrote:
> On Tue, 2006-05-30 at 14:10 +0900, Tejun Heo wrote:
>> Jeff Garzik wrote:
>>> Tejun Heo wrote:
>>>> Jeff Garzik wrote:
>>>>> Tejun Heo wrote:
>>>>>> * I've renamed ata_hotplug_wq to ata_scsi_wq in hotplug patches.  I 
>>>>>> think rescan can use this wq instead of creating its own.
>>>>> I think we will use this workqueue even when SCSI is optional, so 
>>>>> ata_scsi_wq may not be the best name, long term.  I ACK'd its 
>>>>> inclusion of course, so not a big deal.
>>>> As it seems there will be another round of hotplug patches, I can 
>>>> rename it without too much trouble.  My candidates are...
>>>>
>>>> ata_aux_wq
>>>> ata_management_wq / ata_mgmt_wq
>>>> ata_errands_wq
>>> Another thing to consider is using the kthread API, ignore workqueues, 
>>> and simply creating "one-shot" threads as needed.
>> It wouldn't work for SCSI hotplug.  It depends on that there is only one 
>> thread running the thing, so I think wq is the better choice.  Any 
>> suggestion on naming?
> 
> ata_misc_wq?
> ata_sweep_wq?

I think I'm going with ata_aux_wq.

-- 
tejun

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2006-05-30  7:22 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-05-25  9:02 [PATCH] Snoop SET FEATURES - WRITE CACHE ENABLE/DISABLE command zhao, forrest
2006-05-27  0:15 ` Jeff Garzik
2006-05-29  6:35   ` zhao, forrest
2006-05-29 11:29     ` Mark Lord
2006-05-29  9:08   ` Tejun Heo
2006-05-29  9:18     ` zhao, forrest
2006-05-29  9:46       ` Tejun Heo
2006-05-29  9:20     ` Jeff Garzik
2006-05-29  9:43       ` Tejun Heo
2006-05-30  3:57         ` Jeff Garzik
2006-05-30  4:41     ` Jeff Garzik
2006-05-30  4:50       ` Tejun Heo
2006-05-30  4:57         ` Jeff Garzik
2006-05-30  5:10           ` Tejun Heo
2006-05-30  5:08             ` zhao, forrest
2006-05-30  7:22               ` Tejun Heo

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.