aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorDon Brace <don.brace@microsemi.com>2016-07-01 14:37:31 -0400
committerMartin K. Petersen <martin.petersen@oracle.com>2016-07-15 15:40:39 -0400
commit64ce60cab24603ac0fcd59c9fbc3be78f4c4d229 (patch)
treec45c5bc174ed56461c455b22c90c0735068d321a /drivers/scsi
parent094f71c70b5c25176709081cedda23228a0d82ab (diff)
hpsa: correct skipping masked peripherals
The SA controller spins down RAID drive spares. A REGNEWD event causes an inquiry to be sent to all physical drives. This causes the SA controller to spin up the spare. The controller suspends all I/O to a logical volume until the spare is spun up. The spin-up can take over 50 seconds. This can result in one or both of the following: - SML sends down aborts and resets to the logical volume and can cause the logical volume to be off-lined. - a negative impact on the logical volume's I/O performance each time a REGNEWD is triggered. Reviewed-by: Scott Teel <scott.teel@microsemi.com> Reviewed-by: Kevin Barnett <kevin.barnett@microsemi.com> Signed-off-by: Don Brace <don.brace@microsemi.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/hpsa.c79
1 files changed, 74 insertions, 5 deletions
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index ff8dcd5b0631..375a39632a7a 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -4105,6 +4105,70 @@ static int hpsa_set_local_logical_count(struct ctlr_info *h,
4105 return rc; 4105 return rc;
4106} 4106}
4107 4107
4108static bool hpsa_is_disk_spare(struct ctlr_info *h, u8 *lunaddrbytes)
4109{
4110 struct bmic_identify_physical_device *id_phys;
4111 bool is_spare = false;
4112 int rc;
4113
4114 id_phys = kzalloc(sizeof(*id_phys), GFP_KERNEL);
4115 if (!id_phys)
4116 return false;
4117
4118 rc = hpsa_bmic_id_physical_device(h,
4119 lunaddrbytes,
4120 GET_BMIC_DRIVE_NUMBER(lunaddrbytes),
4121 id_phys, sizeof(*id_phys));
4122 if (rc == 0)
4123 is_spare = (id_phys->more_flags >> 6) & 0x01;
4124
4125 kfree(id_phys);
4126 return is_spare;
4127}
4128
4129#define RPL_DEV_FLAG_NON_DISK 0x1
4130#define RPL_DEV_FLAG_UNCONFIG_DISK_REPORTING_SUPPORTED 0x2
4131#define RPL_DEV_FLAG_UNCONFIG_DISK 0x4
4132
4133#define BMIC_DEVICE_TYPE_ENCLOSURE 6
4134
4135static bool hpsa_skip_device(struct ctlr_info *h, u8 *lunaddrbytes,
4136 struct ext_report_lun_entry *rle)
4137{
4138 u8 device_flags;
4139 u8 device_type;
4140
4141 if (!MASKED_DEVICE(lunaddrbytes))
4142 return false;
4143
4144 device_flags = rle->device_flags;
4145 device_type = rle->device_type;
4146
4147 if (device_flags & RPL_DEV_FLAG_NON_DISK) {
4148 if (device_type == BMIC_DEVICE_TYPE_ENCLOSURE)
4149 return false;
4150 return true;
4151 }
4152
4153 if (!(device_flags & RPL_DEV_FLAG_UNCONFIG_DISK_REPORTING_SUPPORTED))
4154 return false;
4155
4156 if (device_flags & RPL_DEV_FLAG_UNCONFIG_DISK)
4157 return false;
4158
4159 /*
4160 * Spares may be spun down, we do not want to
4161 * do an Inquiry to a RAID set spare drive as
4162 * that would have them spun up, that is a
4163 * performance hit because I/O to the RAID device
4164 * stops while the spin up occurs which can take
4165 * over 50 seconds.
4166 */
4167 if (hpsa_is_disk_spare(h, lunaddrbytes))
4168 return true;
4169
4170 return false;
4171}
4108 4172
4109static void hpsa_update_scsi_devices(struct ctlr_info *h) 4173static void hpsa_update_scsi_devices(struct ctlr_info *h)
4110{ 4174{
@@ -4198,6 +4262,7 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h)
4198 u8 *lunaddrbytes, is_OBDR = 0; 4262 u8 *lunaddrbytes, is_OBDR = 0;
4199 int rc = 0; 4263 int rc = 0;
4200 int phys_dev_index = i - (raid_ctlr_position == 0); 4264 int phys_dev_index = i - (raid_ctlr_position == 0);
4265 bool skip_device = false;
4201 4266
4202 physical_device = i < nphysicals + (raid_ctlr_position == 0); 4267 physical_device = i < nphysicals + (raid_ctlr_position == 0);
4203 4268
@@ -4205,11 +4270,15 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h)
4205 lunaddrbytes = figure_lunaddrbytes(h, raid_ctlr_position, 4270 lunaddrbytes = figure_lunaddrbytes(h, raid_ctlr_position,
4206 i, nphysicals, nlogicals, physdev_list, logdev_list); 4271 i, nphysicals, nlogicals, physdev_list, logdev_list);
4207 4272
4208 /* skip masked non-disk devices */ 4273 /*
4209 if (MASKED_DEVICE(lunaddrbytes) && physical_device && 4274 * Skip over some devices such as a spare.
4210 (physdev_list->LUN[phys_dev_index].device_type != 0x06) && 4275 */
4211 (physdev_list->LUN[phys_dev_index].device_flags & 0x01)) 4276 if (!tmpdevice->external && physical_device) {
4212 continue; 4277 skip_device = hpsa_skip_device(h, lunaddrbytes,
4278 &physdev_list->LUN[phys_dev_index]);
4279 if (skip_device)
4280 continue;
4281 }
4213 4282
4214 /* Get device type, vendor, model, device id */ 4283 /* Get device type, vendor, model, device id */
4215 rc = hpsa_update_device_info(h, lunaddrbytes, tmpdevice, 4284 rc = hpsa_update_device_info(h, lunaddrbytes, tmpdevice,