[SCSI] mptfusion : dv performance fix

Syncronization for Domain Validation workqueue and the initiation of the
alternate controller. Its possible that dv could be terminated if the
workqueue on the 1st channel doesn complete in time before the 2nd channel
begins initialization.

Signed-off-by: Eric Moore <Eric.Moore@lsil.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>

authored by Moore, Eric Dean and committed by James Bottomley 2a238ea5 8b2f8138

+75 -2
+62 -2
drivers/message/fusion/mptbase.c
··· 1118 1118 return -1; 1119 1119 } 1120 1120 1121 + int 1122 + mpt_alt_ioc_wait(MPT_ADAPTER *ioc) 1123 + { 1124 + int loop_count = 30 * 4; /* Wait 30 seconds */ 1125 + int status = -1; /* -1 means failed to get board READY */ 1126 + 1127 + do { 1128 + spin_lock(&ioc->initializing_hba_lock); 1129 + if (ioc->initializing_hba_lock_flag == 0) { 1130 + ioc->initializing_hba_lock_flag=1; 1131 + spin_unlock(&ioc->initializing_hba_lock); 1132 + status = 0; 1133 + break; 1134 + } 1135 + spin_unlock(&ioc->initializing_hba_lock); 1136 + set_current_state(TASK_INTERRUPTIBLE); 1137 + schedule_timeout(HZ/4); 1138 + } while (--loop_count); 1139 + 1140 + return status; 1141 + } 1142 + 1143 + /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1144 + /* 1145 + * mpt_bringup_adapter - This is a wrapper function for mpt_do_ioc_recovery 1146 + * @ioc: Pointer to MPT adapter structure 1147 + * @sleepFlag: Use schedule if CAN_SLEEP else use udelay. 1148 + * 1149 + * This routine performs all the steps necessary to bring the IOC 1150 + * to a OPERATIONAL state. 1151 + * 1152 + * Special Note: This function was added with spin lock's so as to allow 1153 + * the dv(domain validation) work thread to succeed on the other channel 1154 + * that maybe occuring at the same time when this function is called. 1155 + * Without this lock, the dv would fail when message frames were 1156 + * requested during hba bringup on the alternate ioc. 1157 + */ 1158 + static int 1159 + mpt_bringup_adapter(MPT_ADAPTER *ioc, int sleepFlag) 1160 + { 1161 + int r; 1162 + 1163 + if(ioc->alt_ioc) { 1164 + if((r=mpt_alt_ioc_wait(ioc->alt_ioc)!=0)) 1165 + return r; 1166 + } 1167 + 1168 + r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP, 1169 + CAN_SLEEP); 1170 + 1171 + if(ioc->alt_ioc) { 1172 + spin_lock(&ioc->alt_ioc->initializing_hba_lock); 1173 + ioc->alt_ioc->initializing_hba_lock_flag=0; 1174 + spin_unlock(&ioc->alt_ioc->initializing_hba_lock); 1175 + } 1176 + 1177 + return r; 1178 + } 1179 + 1121 1180 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1122 1181 /* 1123 1182 * mpt_attach - Install a PCI intelligent MPT adapter. ··· 1245 1186 ioc->pcidev = pdev; 1246 1187 ioc->diagPending = 0; 1247 1188 spin_lock_init(&ioc->diagLock); 1189 + spin_lock_init(&ioc->initializing_hba_lock); 1248 1190 1249 1191 /* Initialize the event logging. 1250 1192 */ ··· 1468 1408 */ 1469 1409 mpt_detect_bound_ports(ioc, pdev); 1470 1410 1471 - if ((r = mpt_do_ioc_recovery(ioc, 1472 - MPT_HOSTEVENT_IOC_BRINGUP, CAN_SLEEP)) != 0) { 1411 + if ((r = mpt_bringup_adapter(ioc, CAN_SLEEP)) != 0){ 1473 1412 printk(KERN_WARNING MYNAM 1474 1413 ": WARNING - %s did not initialize properly! (%d)\n", 1475 1414 ioc->name, r); ··· 6355 6296 EXPORT_SYMBOL(mpt_alloc_fw_memory); 6356 6297 EXPORT_SYMBOL(mpt_free_fw_memory); 6357 6298 EXPORT_SYMBOL(mptbase_sas_persist_operation); 6299 + EXPORT_SYMBOL(mpt_alt_ioc_wait); 6358 6300 6359 6301 6360 6302 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+3
drivers/message/fusion/mptbase.h
··· 611 611 int DoneCtx; 612 612 int TaskCtx; 613 613 int InternalCtx; 614 + spinlock_t initializing_hba_lock; 615 + int initializing_hba_lock_flag; 614 616 struct list_head list; 615 617 struct net_device *netdev; 616 618 struct list_head sas_topology; ··· 1003 1001 extern int mpt_findImVolumes(MPT_ADAPTER *ioc); 1004 1002 extern int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc); 1005 1003 extern int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode); 1004 + extern int mpt_alt_ioc_wait(MPT_ADAPTER *ioc); 1006 1005 1007 1006 /* 1008 1007 * Public data decl's...
+10
drivers/message/fusion/mptscsih.c
··· 4162 4162 } 4163 4163 } 4164 4164 4165 + if(mpt_alt_ioc_wait(hd->ioc)!=0) { 4166 + ddvprintk((MYIOC_s_WARN_FMT "alt_ioc busy!\n", 4167 + hd->ioc->name)); 4168 + continue; 4169 + } 4170 + 4165 4171 if (mptscsih_doDv(hd, 0, id) == 1) { 4166 4172 /* Untagged device was busy, try again 4167 4173 */ ··· 4178 4172 */ 4179 4173 hd->ioc->spi_data.dvStatus[id] &= ~(MPT_SCSICFG_DV_NOT_DONE | MPT_SCSICFG_DV_PENDING); 4180 4174 } 4175 + 4176 + spin_lock(&hd->ioc->initializing_hba_lock); 4177 + hd->ioc->initializing_hba_lock_flag=0; 4178 + spin_unlock(&hd->ioc->initializing_hba_lock); 4181 4179 4182 4180 if (isPhysDisk) { 4183 4181 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {