From 860dc73608a091e0b325218acc2701709d5f221a Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Thu, 19 Nov 2009 17:48:29 -0500 Subject: [SCSI] fix async scan add/remove race resulting in an oops Async scanning introduced a very wide window where the SCSI device is up and running but has not yet been added to sysfs. We delay the adding until all scans have completed to retain the same ordering as sync scanning. This delay in visibility causes an oops if a device is removed before we make it visible because the SCSI removal routines have an inbuilt assumption that if a device is in SDEV_RUNNING state, it must be visible (which is not necessarily true in the async scanning case). Fix this by introducing an additional is_visible flag which we can use to condition the tear down so we do the right thing for running but not yet made visible. Reported-by: Alexey Kuznetsov Signed-off-by: James Bottomley --- include/scsi/scsi_device.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/scsi/scsi_device.h') diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index 9af48cbf003..f097ae340bc 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -145,6 +145,7 @@ struct scsi_device { unsigned retry_hwerror:1; /* Retry HARDWARE_ERROR */ unsigned last_sector_bug:1; /* do not use multisector accesses on SD_LAST_BUGGY_SECTORS */ + unsigned is_visible:1; /* is the device visible in sysfs */ DECLARE_BITMAP(supported_events, SDEV_EVT_MAXBITS); /* supported events */ struct list_head event_list; /* asserted events */ -- cgit v1.2.3 From 4a84067dbfce436b81779e585bf712b02ceee552 Mon Sep 17 00:00:00 2001 From: Vasu Dev Date: Thu, 22 Oct 2009 15:46:33 -0700 Subject: [SCSI] add queue_depth ramp up code Current FC HBA queue_depth ramp up code depends on last queue full time. The sdev already has last_queue_full_time field to track last queue full time but stored value is truncated by last four bits. So this patch updates last_queue_full_time without truncating last 4 bits to store full value and then updates its only current usages in scsi_track_queue_full to ignore last four bits to keep current usages same while also use this field in added ramp up code. Adds scsi_handle_queue_ramp_up to ramp up queue_depth on successful completion of IO. The scsi_handle_queue_ramp_up will do ramp up on all luns of a target, just same as ramp down done on all luns on a target. The ramp up is skipped in case the change_queue_depth is not supported by LLD or already reached to added max_queue_depth. Updates added max_queue_depth on every new update to default queue_depth value. The ramp up is also skipped if lapsed time since either last queue ramp up or down is less than LLD specified queue_ramp_up_period. Adds queue_ramp_up_period to sysfs but only if change_queue_depth is supported since ramp up and queue_ramp_up_period is needed only in case change_queue_depth is supported first. Initializes queue_ramp_up_period to 120HZ jiffies as initial default value, it is same as used in existing lpfc and qla2xxx. -v2 Combined all ramp code into this single patch. -v3 Moves max_queue_depth initialization after slave_configure is called from after slave_alloc calling done. Also adjusted max_queue_depth check to skip ramp up if current queue_depth is >= max_queue_depth. -v4 Changes sdev->queue_ramp_up_period unit to ms when using sysfs i/f to store or show its value. Signed-off-by: Vasu Dev Tested-by: Christof Schmitt Tested-by: Giridhar Malavali Signed-off-by: James Bottomley --- include/scsi/scsi_device.h | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'include/scsi/scsi_device.h') diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index 9af48cbf003..92c4c3bd916 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -81,11 +81,14 @@ struct scsi_device { struct list_head starved_entry; struct scsi_cmnd *current_cmnd; /* currently active command */ unsigned short queue_depth; /* How deep of a queue we want */ + unsigned short max_queue_depth; /* max queue depth */ unsigned short last_queue_full_depth; /* These two are used by */ unsigned short last_queue_full_count; /* scsi_track_queue_full() */ - unsigned long last_queue_full_time;/* don't let QUEUE_FULLs on the same - jiffie count on our counter, they - could all be from the same event. */ + unsigned long last_queue_full_time; /* last queue full time */ + unsigned long queue_ramp_up_period; /* ramp up period in jiffies */ +#define SCSI_DEFAULT_RAMP_UP_PERIOD (120 * HZ) + + unsigned long last_queue_ramp_up; /* last queue ramp up time */ unsigned int id, lun, channel; -- cgit v1.2.3 From 3ae31f6a7b6e442fc6a92f29330fbad230dc3992 Mon Sep 17 00:00:00 2001 From: Chandra Seetharaman Date: Wed, 21 Oct 2009 09:22:46 -0700 Subject: [SCSI] scsi_dh: Change the scsidh_activate interface to be asynchronous Make scsi_dh_activate() function asynchronous, by taking in two additional parameters, one is the callback function and the other is the data to call the callback function with. Signed-off-by: Chandra Seetharaman Signed-off-by: James Bottomley --- include/scsi/scsi_device.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include/scsi/scsi_device.h') diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index 92c4c3bd916..68d185c79ba 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -177,6 +177,7 @@ struct scsi_dh_devlist { char *model; }; +typedef void (*activate_complete)(void *, int); struct scsi_device_handler { /* Used by the infrastructure */ struct list_head list; /* list of scsi_device_handlers */ @@ -188,7 +189,7 @@ struct scsi_device_handler { int (*check_sense)(struct scsi_device *, struct scsi_sense_hdr *); int (*attach)(struct scsi_device *); void (*detach)(struct scsi_device *); - int (*activate)(struct scsi_device *); + int (*activate)(struct scsi_device *, activate_complete, void *); int (*prep_fn)(struct scsi_device *, struct request *); int (*set_params)(struct scsi_device *, const char *); }; -- cgit v1.2.3