mirror of
https://github.com/torvalds/linux.git
synced 2024-12-04 01:51:34 +00:00
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>
This commit is contained in:
parent
094f71c70b
commit
64ce60cab2
@ -4105,6 +4105,70 @@ static int hpsa_set_local_logical_count(struct ctlr_info *h,
|
||||
return rc;
|
||||
}
|
||||
|
||||
static bool hpsa_is_disk_spare(struct ctlr_info *h, u8 *lunaddrbytes)
|
||||
{
|
||||
struct bmic_identify_physical_device *id_phys;
|
||||
bool is_spare = false;
|
||||
int rc;
|
||||
|
||||
id_phys = kzalloc(sizeof(*id_phys), GFP_KERNEL);
|
||||
if (!id_phys)
|
||||
return false;
|
||||
|
||||
rc = hpsa_bmic_id_physical_device(h,
|
||||
lunaddrbytes,
|
||||
GET_BMIC_DRIVE_NUMBER(lunaddrbytes),
|
||||
id_phys, sizeof(*id_phys));
|
||||
if (rc == 0)
|
||||
is_spare = (id_phys->more_flags >> 6) & 0x01;
|
||||
|
||||
kfree(id_phys);
|
||||
return is_spare;
|
||||
}
|
||||
|
||||
#define RPL_DEV_FLAG_NON_DISK 0x1
|
||||
#define RPL_DEV_FLAG_UNCONFIG_DISK_REPORTING_SUPPORTED 0x2
|
||||
#define RPL_DEV_FLAG_UNCONFIG_DISK 0x4
|
||||
|
||||
#define BMIC_DEVICE_TYPE_ENCLOSURE 6
|
||||
|
||||
static bool hpsa_skip_device(struct ctlr_info *h, u8 *lunaddrbytes,
|
||||
struct ext_report_lun_entry *rle)
|
||||
{
|
||||
u8 device_flags;
|
||||
u8 device_type;
|
||||
|
||||
if (!MASKED_DEVICE(lunaddrbytes))
|
||||
return false;
|
||||
|
||||
device_flags = rle->device_flags;
|
||||
device_type = rle->device_type;
|
||||
|
||||
if (device_flags & RPL_DEV_FLAG_NON_DISK) {
|
||||
if (device_type == BMIC_DEVICE_TYPE_ENCLOSURE)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(device_flags & RPL_DEV_FLAG_UNCONFIG_DISK_REPORTING_SUPPORTED))
|
||||
return false;
|
||||
|
||||
if (device_flags & RPL_DEV_FLAG_UNCONFIG_DISK)
|
||||
return false;
|
||||
|
||||
/*
|
||||
* Spares may be spun down, we do not want to
|
||||
* do an Inquiry to a RAID set spare drive as
|
||||
* that would have them spun up, that is a
|
||||
* performance hit because I/O to the RAID device
|
||||
* stops while the spin up occurs which can take
|
||||
* over 50 seconds.
|
||||
*/
|
||||
if (hpsa_is_disk_spare(h, lunaddrbytes))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void hpsa_update_scsi_devices(struct ctlr_info *h)
|
||||
{
|
||||
@ -4198,6 +4262,7 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h)
|
||||
u8 *lunaddrbytes, is_OBDR = 0;
|
||||
int rc = 0;
|
||||
int phys_dev_index = i - (raid_ctlr_position == 0);
|
||||
bool skip_device = false;
|
||||
|
||||
physical_device = i < nphysicals + (raid_ctlr_position == 0);
|
||||
|
||||
@ -4205,11 +4270,15 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h)
|
||||
lunaddrbytes = figure_lunaddrbytes(h, raid_ctlr_position,
|
||||
i, nphysicals, nlogicals, physdev_list, logdev_list);
|
||||
|
||||
/* skip masked non-disk devices */
|
||||
if (MASKED_DEVICE(lunaddrbytes) && physical_device &&
|
||||
(physdev_list->LUN[phys_dev_index].device_type != 0x06) &&
|
||||
(physdev_list->LUN[phys_dev_index].device_flags & 0x01))
|
||||
continue;
|
||||
/*
|
||||
* Skip over some devices such as a spare.
|
||||
*/
|
||||
if (!tmpdevice->external && physical_device) {
|
||||
skip_device = hpsa_skip_device(h, lunaddrbytes,
|
||||
&physdev_list->LUN[phys_dev_index]);
|
||||
if (skip_device)
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Get device type, vendor, model, device id */
|
||||
rc = hpsa_update_device_info(h, lunaddrbytes, tmpdevice,
|
||||
|
Loading…
Reference in New Issue
Block a user