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

mpt3sas: Used "synchronize_irq()"API to synchronize timed-out IO & TMs

Replaced mpt3sas_base_flush_reply_queues() with
mpt3sas_base_sync_reply_irqs(),as mpt3sas_base_flush_reply_queues()
skips over reply queues that are currently busy (i.e. being handled by
interrupt processing in another core). If a reply queue is busy, then
call to synchronize_irq()in mpt3sas_base_sync_reply_irqs()make sures the
other core has finished flushing the queue and completed any calls to
the mid-layer scsi_done() routine.

Signed-off-by: Chaitra P B <chaitra.basappa@broadcom.com>
Reviewed-by: Tomas Henzl <thenzl@redhat.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>

authored by

Chaitra P B and committed by
Martin K. Petersen
5f0dfb7a 6c197093

+12 -10
+7 -8
drivers/scsi/mpt3sas/mpt3sas_base.c
··· 1104 1104 } 1105 1105 1106 1106 /** 1107 - * mpt3sas_base_flush_reply_queues - flushing the MSIX reply queues 1107 + * mpt3sas_base_sync_reply_irqs - flush pending MSIX interrupts 1108 1108 * @ioc: per adapter object 1109 - * Context: ISR conext 1109 + * Context: non ISR conext 1110 1110 * 1111 - * Called when a Task Management request has completed. We want 1112 - * to flush the other reply queues so all the outstanding IO has been 1113 - * completed back to OS before we process the TM completetion. 1111 + * Called when a Task Management request has completed. 1114 1112 * 1115 1113 * Return nothing. 1116 1114 */ 1117 1115 void 1118 - mpt3sas_base_flush_reply_queues(struct MPT3SAS_ADAPTER *ioc) 1116 + mpt3sas_base_sync_reply_irqs(struct MPT3SAS_ADAPTER *ioc) 1119 1117 { 1120 1118 struct adapter_reply_queue *reply_q; 1121 1119 ··· 1124 1126 return; 1125 1127 1126 1128 list_for_each_entry(reply_q, &ioc->reply_queue_list, list) { 1127 - if (ioc->shost_recovery) 1129 + if (ioc->shost_recovery || ioc->remove_host || 1130 + ioc->pci_error_recovery) 1128 1131 return; 1129 1132 /* TMs are on msix_index == 0 */ 1130 1133 if (reply_q->msix_index == 0) 1131 1134 continue; 1132 - _base_interrupt(reply_q->vector, (void *)reply_q); 1135 + synchronize_irq(reply_q->vector); 1133 1136 } 1134 1137 } 1135 1138
+2 -1
drivers/scsi/mpt3sas/mpt3sas_base.h
··· 1236 1236 void *mpt3sas_base_get_sense_buffer(struct MPT3SAS_ADAPTER *ioc, u16 smid); 1237 1237 __le32 mpt3sas_base_get_sense_buffer_dma(struct MPT3SAS_ADAPTER *ioc, 1238 1238 u16 smid); 1239 - void mpt3sas_base_flush_reply_queues(struct MPT3SAS_ADAPTER *ioc); 1239 + 1240 + void mpt3sas_base_sync_reply_irqs(struct MPT3SAS_ADAPTER *ioc); 1240 1241 1241 1242 /* hi-priority queue */ 1242 1243 u16 mpt3sas_base_get_smid_hpr(struct MPT3SAS_ADAPTER *ioc, u8 cb_idx);
+3 -1
drivers/scsi/mpt3sas/mpt3sas_scsih.c
··· 2124 2124 return 1; 2125 2125 if (ioc->tm_cmds.smid != smid) 2126 2126 return 1; 2127 - mpt3sas_base_flush_reply_queues(ioc); 2128 2127 ioc->tm_cmds.status |= MPT3_CMD_COMPLETE; 2129 2128 mpi_reply = mpt3sas_base_get_reply_virt_addr(ioc, reply); 2130 2129 if (mpi_reply) { ··· 2307 2308 goto err_out; 2308 2309 } 2309 2310 } 2311 + 2312 + /* sync IRQs in case those were busy during flush. */ 2313 + mpt3sas_base_sync_reply_irqs(ioc); 2310 2314 2311 2315 if (ioc->tm_cmds.status & MPT3_CMD_REPLY_VALID) { 2312 2316 mpt3sas_trigger_master(ioc, MASTER_TRIGGER_TASK_MANAGMENT);