ipr: add support for async scanning to speed up boot

Switch device scanning logic in the ipr driver to use
the async scan API. This speeds up boot times, particularly
on large systems.

Signed-off-by: Brian King <brking@linux.vnet.ibm.com>
Reviewed-by: Wen Xiong<wenxiong@linux.vnet.ibm.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>

authored by

Brian King and committed by
Christoph Hellwig
f688f96d f49accf1

+44 -48
+43 -45
drivers/scsi/ipr.c
··· 1426 1426 if (res->sdev) { 1427 1427 res->del_from_ml = 1; 1428 1428 res->res_handle = IPR_INVALID_RES_HANDLE; 1429 - if (ioa_cfg->allow_ml_add_del) 1430 - schedule_work(&ioa_cfg->work_q); 1429 + schedule_work(&ioa_cfg->work_q); 1431 1430 } else { 1432 1431 ipr_clear_res_target(res); 1433 1432 list_move_tail(&res->queue, &ioa_cfg->free_res_q); 1434 1433 } 1435 1434 } else if (!res->sdev || res->del_from_ml) { 1436 1435 res->add_to_ml = 1; 1437 - if (ioa_cfg->allow_ml_add_del) 1438 - schedule_work(&ioa_cfg->work_q); 1436 + schedule_work(&ioa_cfg->work_q); 1439 1437 } 1440 1438 1441 1439 ipr_send_hcam(ioa_cfg, IPR_HCAM_CDB_OP_CODE_CONFIG_CHANGE, hostrcb); ··· 3271 3273 restart: 3272 3274 do { 3273 3275 did_work = 0; 3274 - if (!ioa_cfg->hrrq[IPR_INIT_HRRQ].allow_cmds || 3275 - !ioa_cfg->allow_ml_add_del) { 3276 + if (!ioa_cfg->hrrq[IPR_INIT_HRRQ].allow_cmds) { 3276 3277 spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); 3277 3278 return; 3278 3279 } ··· 3308 3311 } 3309 3312 } 3310 3313 3314 + ioa_cfg->scan_done = 1; 3311 3315 spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); 3312 3316 kobject_uevent(&ioa_cfg->host->shost_dev.kobj, KOBJ_CHANGE); 3313 3317 LEAVE; ··· 5205 5207 * @scsi_cmd: scsi command struct 5206 5208 * 5207 5209 * Return value: 5210 + * 0 if scan in progress / 1 if scan is complete 5211 + **/ 5212 + static int ipr_scan_finished(struct Scsi_Host *shost, unsigned long elapsed_time) 5213 + { 5214 + unsigned long lock_flags; 5215 + struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *) shost->hostdata; 5216 + int rc = 0; 5217 + 5218 + spin_lock_irqsave(shost->host_lock, lock_flags); 5219 + if (ioa_cfg->hrrq[IPR_INIT_HRRQ].ioa_is_dead || ioa_cfg->scan_done) 5220 + rc = 1; 5221 + if ((elapsed_time/HZ) > (ioa_cfg->transop_timeout * 2)) 5222 + rc = 1; 5223 + spin_unlock_irqrestore(shost->host_lock, lock_flags); 5224 + return rc; 5225 + } 5226 + 5227 + /** 5228 + * ipr_eh_host_reset - Reset the host adapter 5229 + * @scsi_cmd: scsi command struct 5230 + * 5231 + * Return value: 5208 5232 * SUCCESS / FAILED 5209 5233 **/ 5210 5234 static int ipr_eh_abort(struct scsi_cmnd *scsi_cmd) ··· 6295 6275 .slave_alloc = ipr_slave_alloc, 6296 6276 .slave_configure = ipr_slave_configure, 6297 6277 .slave_destroy = ipr_slave_destroy, 6278 + .scan_finished = ipr_scan_finished, 6298 6279 .target_alloc = ipr_target_alloc, 6299 6280 .target_destroy = ipr_target_destroy, 6300 6281 .change_queue_depth = ipr_change_queue_depth, ··· 6837 6816 ioa_cfg->doorbell |= IPR_RUNTIME_RESET; 6838 6817 6839 6818 list_for_each_entry(res, &ioa_cfg->used_res_q, queue) { 6840 - if (ioa_cfg->allow_ml_add_del && (res->add_to_ml || res->del_from_ml)) { 6819 + if (res->add_to_ml || res->del_from_ml) { 6841 6820 ipr_trace; 6842 6821 break; 6843 6822 } ··· 6866 6845 if (!ioa_cfg->hrrq[IPR_INIT_HRRQ].allow_cmds) 6867 6846 scsi_block_requests(ioa_cfg->host); 6868 6847 6848 + schedule_work(&ioa_cfg->work_q); 6869 6849 LEAVE; 6870 6850 return IPR_RC_JOB_RETURN; 6871 6851 } ··· 7606 7584 memcpy(type, ioa_cfg->vpd_cbs->ioa_vpd.std_inq_data.vpids.product_id, 4); 7607 7585 type[4] = '\0'; 7608 7586 ioa_cfg->type = simple_strtoul((char *)type, NULL, 16); 7587 + 7588 + if (ipr_invalid_adapter(ioa_cfg)) { 7589 + dev_err(&ioa_cfg->pdev->dev, 7590 + "Adapter not supported in this hardware configuration.\n"); 7591 + 7592 + if (!ipr_testmode) { 7593 + ioa_cfg->reset_retries += IPR_NUM_RESET_RELOAD_RETRIES; 7594 + ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NONE); 7595 + list_add_tail(&ipr_cmd->queue, 7596 + &ioa_cfg->hrrq->hrrq_free_q); 7597 + return IPR_RC_JOB_RETURN; 7598 + } 7599 + } 7609 7600 7610 7601 ipr_cmd->job_step = ipr_ioafp_page3_inquiry; 7611 7602 ··· 8807 8772 _ipr_initiate_ioa_reset(ioa_cfg, ipr_reset_enable_ioa, 8808 8773 IPR_SHUTDOWN_NONE); 8809 8774 spin_unlock_irqrestore(ioa_cfg->host->host_lock, host_lock_flags); 8810 - wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload); 8811 - spin_lock_irqsave(ioa_cfg->host->host_lock, host_lock_flags); 8812 - 8813 - if (ioa_cfg->hrrq[IPR_INIT_HRRQ].ioa_is_dead) { 8814 - rc = -EIO; 8815 - } else if (ipr_invalid_adapter(ioa_cfg)) { 8816 - if (!ipr_testmode) 8817 - rc = -EIO; 8818 - 8819 - dev_err(&ioa_cfg->pdev->dev, 8820 - "Adapter not supported in this hardware configuration.\n"); 8821 - } 8822 - 8823 - spin_unlock_irqrestore(ioa_cfg->host->host_lock, host_lock_flags); 8824 8775 8825 8776 LEAVE; 8826 8777 return rc; ··· 9260 9239 * ioa_cfg->max_devs_supported))); 9261 9240 } 9262 9241 9263 - host->max_channel = IPR_MAX_BUS_TO_SCAN; 9242 + host->max_channel = IPR_VSET_BUS; 9264 9243 host->unique_id = host->host_no; 9265 9244 host->max_cmd_len = IPR_MAX_CDB_LEN; 9266 9245 host->can_queue = ioa_cfg->max_cmds; ··· 9760 9739 } 9761 9740 9762 9741 /** 9763 - * ipr_scan_vsets - Scans for VSET devices 9764 - * @ioa_cfg: ioa config struct 9765 - * 9766 - * Description: Since the VSET resources do not follow SAM in that we can have 9767 - * sparse LUNs with no LUN 0, we have to scan for these ourselves. 9768 - * 9769 - * Return value: 9770 - * none 9771 - **/ 9772 - static void ipr_scan_vsets(struct ipr_ioa_cfg *ioa_cfg) 9773 - { 9774 - int target, lun; 9775 - 9776 - for (target = 0; target < IPR_MAX_NUM_TARGETS_PER_BUS; target++) 9777 - for (lun = 0; lun < IPR_MAX_NUM_VSET_LUNS_PER_TARGET; lun++) 9778 - scsi_add_device(ioa_cfg->host, IPR_VSET_BUS, target, lun); 9779 - } 9780 - 9781 - /** 9782 9742 * ipr_initiate_ioa_bringdown - Bring down an adapter 9783 9743 * @ioa_cfg: ioa config struct 9784 9744 * @shutdown_type: shutdown type ··· 9914 9912 } 9915 9913 9916 9914 scsi_scan_host(ioa_cfg->host); 9917 - ipr_scan_vsets(ioa_cfg); 9918 - scsi_add_device(ioa_cfg->host, IPR_IOA_BUS, IPR_IOA_TARGET, IPR_IOA_LUN); 9919 - ioa_cfg->allow_ml_add_del = 1; 9920 - ioa_cfg->host->max_channel = IPR_VSET_BUS; 9921 9915 ioa_cfg->iopoll_weight = ioa_cfg->chip_cfg->iopoll_weight; 9922 9916 9923 9917 if (ioa_cfg->iopoll_weight && ioa_cfg->sis64 && ioa_cfg->nvectors > 1) {
+1 -3
drivers/scsi/ipr.h
··· 157 157 158 158 #define IPR_MAX_NUM_TARGETS_PER_BUS 256 159 159 #define IPR_MAX_NUM_LUNS_PER_TARGET 256 160 - #define IPR_MAX_NUM_VSET_LUNS_PER_TARGET 8 161 160 #define IPR_VSET_BUS 0xff 162 161 #define IPR_IOA_BUS 0xff 163 162 #define IPR_IOA_TARGET 0xff 164 163 #define IPR_IOA_LUN 0xff 165 164 #define IPR_MAX_NUM_BUSES 16 166 - #define IPR_MAX_BUS_TO_SCAN IPR_MAX_NUM_BUSES 167 165 168 166 #define IPR_NUM_RESET_RELOAD_RETRIES 3 169 167 ··· 1451 1453 u8 in_ioa_bringdown:1; 1452 1454 u8 ioa_unit_checked:1; 1453 1455 u8 dump_taken:1; 1454 - u8 allow_ml_add_del:1; 1456 + u8 scan_done:1; 1455 1457 u8 needs_hard_reset:1; 1456 1458 u8 dual_raid:1; 1457 1459 u8 needs_warm_reset:1;