Skip to contentSkip to conversation

add back single_lun support

PATCH In review Patrick Mansfield 3 participants 4 messages Feb 5, 2003 – Feb 6, 2003 SCSI

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 add back single_lun support

This patch against the current scsi-misc-2.5 adds back the check for the single_lun case.

I compiled and booted with this applied but don't have any devices (i.e. CD ROM changer) for testing.

drivers/scsi/scsi_lib.c +19 -0
@@ -787,6 +787,22 @@
 	return ret;
 }
 
+/*
+ * The target associated with myself can only handle one active command at
+ * a time. Scan through all of the luns on the same target as myself,
+ * return 1 if any are active.
+ */
+static int check_all_luns(struct scsi_device *myself)
+{
+	struct scsi_device *sdev;
+
+	list_for_each_entry(sdev, &myself->same_target_siblings,
+			    same_target_siblings)
+		if (atomic_read(&sdev->device_active))
+			return 1;
+	return 0;
+}
+
 int scsi_prep_fn(struct request_queue *q, struct request *req)
 {
 	struct Scsi_Device_Template *STpnt;
@@ -948,6 +964,9 @@
 		req = elv_next_request(q);
 
 		if (SDpnt->device_busy >= SDpnt->queue_depth)
+			break;
+
+		if (SDpnt->single_lun && check_all_luns(SDpnt))
 			break;
 
 		if(SHpnt->host_busy == 0 && SHpnt->host_blocked) {

-- Patrick Mansfield

#1 lore raw
Quoted 18 lines · Patrick Mansfield

This patch against the current scsi-misc-2.5 adds back the check for the single_lun case.

I compiled and booted with this applied but don't have any devices (i.e. CD ROM changer) for testing.

drivers/scsi/scsi_lib.c +6 -0
@@ -787,6 +787,22 @@
 	return ret;
 }
 
+/*
+ * The target associated with myself can only handle one active command at
+ * a time. Scan through all of the luns on the same target as myself,
+ * return 1 if any are active.
+ */
+static int check_all_luns(struct scsi_device *myself)

drivers/scsi/scsi_lib.c line 805

Quoted 10 lines
drivers/scsi/scsi_lib.c +10 -0
+{
+	struct scsi_device *sdev;
+
+	list_for_each_entry(sdev, &myself->same_target_siblings,
+			    same_target_siblings)
+		if (atomic_read(&sdev->device_active))
+			return 1;
+	return 0;
+}
+

I don't see device_active getting set anywhere.

shouldn't we just dump device_active in favour of a non-zero check of device_busy (it's all done under the queue lock, anyway).

James

#2 lore raw
Quoted 6 lines · James Bottomley

I don't see device_active getting set anywhere.

shouldn't we just dump device_active in favour of a non-zero check of device_busy (it's all done under the queue lock, anyway).

James

OK - once more.

This patch against the current scsi-misc-2.5 adds back the check for the single_lun case and removes the unused device_active field.

I compiled and booted with this applied but don't have any devices (i.e. CD ROM changer) for testing.

drivers/scsi/scsi.h +0 -1
@@ -570,7 +570,6 @@
 					   device is busy */
 	struct Scsi_Host *host;
 	request_queue_t *request_queue;
-        atomic_t                device_active; /* commands checked out for device */
 	volatile unsigned short device_busy;	/* commands actually active on low-level */
 	struct list_head free_cmnds;    /* list of available Scsi_Cmnd structs */
 	struct list_head busy_cmnds;    /* list of Scsi_Cmnd structs in use */

===== drivers/scsi/scsi_lib.c 1.66 vs edited =====

drivers/scsi/scsi_lib.c +19 -0
@@ -787,6 +787,22 @@
 	return ret;
 }
 
+/*
+ * The target associated with myself can only handle one active command at
+ * a time. Scan through all of the luns on the same target as myself,
+ * return 1 if any are active.
+ */
+static int check_all_luns(struct scsi_device *myself)
+{
+	struct scsi_device *sdev;
+
+	list_for_each_entry(sdev, &myself->same_target_siblings,
+			    same_target_siblings)
+		if (sdev->device_busy)
+			return 1;
+	return 0;
+}
+
 int scsi_prep_fn(struct request_queue *q, struct request *req)
 {
 	struct Scsi_Device_Template *STpnt;
@@ -948,6 +964,9 @@
 		req = elv_next_request(q);
 
 		if (SDpnt->device_busy >= SDpnt->queue_depth)
+			break;
+
+		if (SDpnt->single_lun && check_all_luns(SDpnt))
 			break;
 
 		if(SHpnt->host_busy == 0 && SHpnt->host_blocked) {

-- Patrick Mansfield

#3 lore raw
In reply to James Bottomley
Quoted 1 line · James Bottomley

I don't see device_active getting set anywhere.

The same is true for host_active, btw..

drivers/scsi/hosts.c +0 -1
@@ -392,7 +392,6 @@
 
 	spin_lock_init(&shost->default_lock);
 	scsi_assign_lock(shost, &shost->default_lock);
-	atomic_set(&shost->host_active,0);
 	INIT_LIST_HEAD(&shost->my_devices);
 
 	init_waitqueue_head(&shost->host_wait);

===== drivers/scsi/hosts.h 1.51 vs edited =====

drivers/scsi/hosts.h +0 -1
@@ -396,7 +396,6 @@
     unsigned int            eh_kill:1; /* set when killing the eh thread */
     wait_queue_head_t       host_wait;
     Scsi_Host_Template    * hostt;
-    atomic_t                host_active; /* commands checked out */
     volatile unsigned short host_busy;   /* commands actually active on low-level */
     volatile unsigned short host_failed; /* commands that failed. */
     

===== drivers/scsi/scsi.c 1.87 vs edited =====

drivers/scsi/scsi.c +5 -5
@@ -994,11 +994,11 @@
 				 * Here we have a fatal error of some sort.
 				 * Turn it over to the error handler.
 				 */
-				SCSI_LOG_MLCOMPLETE(3, printk("Command failed %p %x active=%d busy=%d failed=%d\n",
-						    SCpnt, SCpnt->result,
-				  atomic_read(&SCpnt->device->host->host_active),
-						  SCpnt->device->host->host_busy,
-					      SCpnt->device->host->host_failed));
+				SCSI_LOG_MLCOMPLETE(3,
+					printk("Command failed %p %x busy=%d failed=%d\n",
+						SCpnt, SCpnt->result,
+						SCpnt->device->host->host_busy,
+						SCpnt->device->host->host_failed));
 
 				/*
 				 * Dump the sense information too.

===== drivers/scsi/scsi_error.c 1.29 vs edited =====

drivers/scsi/scsi_error.c +7 -8
@@ -131,23 +131,22 @@
  **/
 void scsi_times_out(Scsi_Cmnd *scmd)
 {
+	struct Scsi_Host *shost = scmd->device->host;
+
 	/* Set the serial_number_at_timeout to the current serial_number */
 	scmd->serial_number_at_timeout = scmd->serial_number;
 
 	scsi_eh_eflags_set(scmd, SCSI_EH_CMD_TIMEOUT | SCSI_EH_CMD_ERR);
 
-	if( scmd->device->host->eh_wait == NULL ) {
+	if (unlikely(shost->eh_wait == NULL)) {
 		panic("Error handler thread not present at %p %p %s %d",
-		      scmd, scmd->device->host, __FILE__, __LINE__);
+		      scmd, shost, __FILE__, __LINE__);
 	}
 
-	scsi_host_failed_inc_and_test(scmd->device->host);
+	scsi_host_failed_inc_and_test(shost);
 
-	SCSI_LOG_TIMEOUT(3, printk("Command timed out active=%d busy=%d "
-				   " failed=%d\n",
-				   atomic_read(&scmd->device->host->host_active),
-				   scmd->device->host->host_busy,
-				   scmd->device->host->host_failed));
+	SCSI_LOG_TIMEOUT(3, printk("Command timed out busy=%d failed=%d\n",
+				   shost->host_busy, shost->host_failed));
 }
 
 /**
drivers/scsi/scsi_proc.c +1 -2
@@ -345,10 +345,9 @@
 	i = 0;
 	for (shpnt = scsi_host_get_next(NULL); shpnt;
 	     shpnt = scsi_host_get_next(shpnt)) {
-		printk(KERN_INFO " %d %d %d : %d %d\n",
+		printk(KERN_INFO " %d %d : %d %d\n",
 		       shpnt->host_failed,
 		       shpnt->host_busy,
-		       atomic_read(&shpnt->host_active),
 		       shpnt->host_blocked,
 		       shpnt->host_self_blocked);
 	}