Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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 if (res->sdev) { 1427 res->del_from_ml = 1; 1428 res->res_handle = IPR_INVALID_RES_HANDLE; 1429 - if (ioa_cfg->allow_ml_add_del) 1430 - schedule_work(&ioa_cfg->work_q); 1431 } else { 1432 ipr_clear_res_target(res); 1433 list_move_tail(&res->queue, &ioa_cfg->free_res_q); 1434 } 1435 } else if (!res->sdev || res->del_from_ml) { 1436 res->add_to_ml = 1; 1437 - if (ioa_cfg->allow_ml_add_del) 1438 - schedule_work(&ioa_cfg->work_q); 1439 } 1440 1441 ipr_send_hcam(ioa_cfg, IPR_HCAM_CDB_OP_CODE_CONFIG_CHANGE, hostrcb); ··· 3271 restart: 3272 do { 3273 did_work = 0; 3274 - if (!ioa_cfg->hrrq[IPR_INIT_HRRQ].allow_cmds || 3275 - !ioa_cfg->allow_ml_add_del) { 3276 spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); 3277 return; 3278 } ··· 3308 } 3309 } 3310 3311 spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); 3312 kobject_uevent(&ioa_cfg->host->shost_dev.kobj, KOBJ_CHANGE); 3313 LEAVE; ··· 5205 * @scsi_cmd: scsi command struct 5206 * 5207 * Return value: 5208 * SUCCESS / FAILED 5209 **/ 5210 static int ipr_eh_abort(struct scsi_cmnd *scsi_cmd) ··· 6295 .slave_alloc = ipr_slave_alloc, 6296 .slave_configure = ipr_slave_configure, 6297 .slave_destroy = ipr_slave_destroy, 6298 .target_alloc = ipr_target_alloc, 6299 .target_destroy = ipr_target_destroy, 6300 .change_queue_depth = ipr_change_queue_depth, ··· 6837 ioa_cfg->doorbell |= IPR_RUNTIME_RESET; 6838 6839 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)) { 6841 ipr_trace; 6842 break; 6843 } ··· 6866 if (!ioa_cfg->hrrq[IPR_INIT_HRRQ].allow_cmds) 6867 scsi_block_requests(ioa_cfg->host); 6868 6869 LEAVE; 6870 return IPR_RC_JOB_RETURN; 6871 } ··· 7606 memcpy(type, ioa_cfg->vpd_cbs->ioa_vpd.std_inq_data.vpids.product_id, 4); 7607 type[4] = '\0'; 7608 ioa_cfg->type = simple_strtoul((char *)type, NULL, 16); 7609 7610 ipr_cmd->job_step = ipr_ioafp_page3_inquiry; 7611 ··· 8807 _ipr_initiate_ioa_reset(ioa_cfg, ipr_reset_enable_ioa, 8808 IPR_SHUTDOWN_NONE); 8809 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 8825 LEAVE; 8826 return rc; ··· 9260 * ioa_cfg->max_devs_supported))); 9261 } 9262 9263 - host->max_channel = IPR_MAX_BUS_TO_SCAN; 9264 host->unique_id = host->host_no; 9265 host->max_cmd_len = IPR_MAX_CDB_LEN; 9266 host->can_queue = ioa_cfg->max_cmds; ··· 9760 } 9761 9762 /** 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 * ipr_initiate_ioa_bringdown - Bring down an adapter 9783 * @ioa_cfg: ioa config struct 9784 * @shutdown_type: shutdown type ··· 9914 } 9915 9916 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 ioa_cfg->iopoll_weight = ioa_cfg->chip_cfg->iopoll_weight; 9922 9923 if (ioa_cfg->iopoll_weight && ioa_cfg->sis64 && ioa_cfg->nvectors > 1) {
··· 1426 if (res->sdev) { 1427 res->del_from_ml = 1; 1428 res->res_handle = IPR_INVALID_RES_HANDLE; 1429 + schedule_work(&ioa_cfg->work_q); 1430 } else { 1431 ipr_clear_res_target(res); 1432 list_move_tail(&res->queue, &ioa_cfg->free_res_q); 1433 } 1434 } else if (!res->sdev || res->del_from_ml) { 1435 res->add_to_ml = 1; 1436 + schedule_work(&ioa_cfg->work_q); 1437 } 1438 1439 ipr_send_hcam(ioa_cfg, IPR_HCAM_CDB_OP_CODE_CONFIG_CHANGE, hostrcb); ··· 3273 restart: 3274 do { 3275 did_work = 0; 3276 + if (!ioa_cfg->hrrq[IPR_INIT_HRRQ].allow_cmds) { 3277 spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); 3278 return; 3279 } ··· 3311 } 3312 } 3313 3314 + ioa_cfg->scan_done = 1; 3315 spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); 3316 kobject_uevent(&ioa_cfg->host->shost_dev.kobj, KOBJ_CHANGE); 3317 LEAVE; ··· 5207 * @scsi_cmd: scsi command struct 5208 * 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: 5232 * SUCCESS / FAILED 5233 **/ 5234 static int ipr_eh_abort(struct scsi_cmnd *scsi_cmd) ··· 6275 .slave_alloc = ipr_slave_alloc, 6276 .slave_configure = ipr_slave_configure, 6277 .slave_destroy = ipr_slave_destroy, 6278 + .scan_finished = ipr_scan_finished, 6279 .target_alloc = ipr_target_alloc, 6280 .target_destroy = ipr_target_destroy, 6281 .change_queue_depth = ipr_change_queue_depth, ··· 6816 ioa_cfg->doorbell |= IPR_RUNTIME_RESET; 6817 6818 list_for_each_entry(res, &ioa_cfg->used_res_q, queue) { 6819 + if (res->add_to_ml || res->del_from_ml) { 6820 ipr_trace; 6821 break; 6822 } ··· 6845 if (!ioa_cfg->hrrq[IPR_INIT_HRRQ].allow_cmds) 6846 scsi_block_requests(ioa_cfg->host); 6847 6848 + schedule_work(&ioa_cfg->work_q); 6849 LEAVE; 6850 return IPR_RC_JOB_RETURN; 6851 } ··· 7584 memcpy(type, ioa_cfg->vpd_cbs->ioa_vpd.std_inq_data.vpids.product_id, 4); 7585 type[4] = '\0'; 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 + } 7600 7601 ipr_cmd->job_step = ipr_ioafp_page3_inquiry; 7602 ··· 8772 _ipr_initiate_ioa_reset(ioa_cfg, ipr_reset_enable_ioa, 8773 IPR_SHUTDOWN_NONE); 8774 spin_unlock_irqrestore(ioa_cfg->host->host_lock, host_lock_flags); 8775 8776 LEAVE; 8777 return rc; ··· 9239 * ioa_cfg->max_devs_supported))); 9240 } 9241 9242 + host->max_channel = IPR_VSET_BUS; 9243 host->unique_id = host->host_no; 9244 host->max_cmd_len = IPR_MAX_CDB_LEN; 9245 host->can_queue = ioa_cfg->max_cmds; ··· 9739 } 9740 9741 /** 9742 * ipr_initiate_ioa_bringdown - Bring down an adapter 9743 * @ioa_cfg: ioa config struct 9744 * @shutdown_type: shutdown type ··· 9912 } 9913 9914 scsi_scan_host(ioa_cfg->host); 9915 ioa_cfg->iopoll_weight = ioa_cfg->chip_cfg->iopoll_weight; 9916 9917 if (ioa_cfg->iopoll_weight && ioa_cfg->sis64 && ioa_cfg->nvectors > 1) {
+1 -3
drivers/scsi/ipr.h
··· 157 158 #define IPR_MAX_NUM_TARGETS_PER_BUS 256 159 #define IPR_MAX_NUM_LUNS_PER_TARGET 256 160 - #define IPR_MAX_NUM_VSET_LUNS_PER_TARGET 8 161 #define IPR_VSET_BUS 0xff 162 #define IPR_IOA_BUS 0xff 163 #define IPR_IOA_TARGET 0xff 164 #define IPR_IOA_LUN 0xff 165 #define IPR_MAX_NUM_BUSES 16 166 - #define IPR_MAX_BUS_TO_SCAN IPR_MAX_NUM_BUSES 167 168 #define IPR_NUM_RESET_RELOAD_RETRIES 3 169 ··· 1451 u8 in_ioa_bringdown:1; 1452 u8 ioa_unit_checked:1; 1453 u8 dump_taken:1; 1454 - u8 allow_ml_add_del:1; 1455 u8 needs_hard_reset:1; 1456 u8 dual_raid:1; 1457 u8 needs_warm_reset:1;
··· 157 158 #define IPR_MAX_NUM_TARGETS_PER_BUS 256 159 #define IPR_MAX_NUM_LUNS_PER_TARGET 256 160 #define IPR_VSET_BUS 0xff 161 #define IPR_IOA_BUS 0xff 162 #define IPR_IOA_TARGET 0xff 163 #define IPR_IOA_LUN 0xff 164 #define IPR_MAX_NUM_BUSES 16 165 166 #define IPR_NUM_RESET_RELOAD_RETRIES 3 167 ··· 1453 u8 in_ioa_bringdown:1; 1454 u8 ioa_unit_checked:1; 1455 u8 dump_taken:1; 1456 + u8 scan_done:1; 1457 u8 needs_hard_reset:1; 1458 u8 dual_raid:1; 1459 u8 needs_warm_reset:1;