Commit 5f0dfb7a authored by Chaitra P B's avatar Chaitra P B Committed by Martin K. Petersen

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: default avatarChaitra P B <chaitra.basappa@broadcom.com>
Reviewed-by: default avatarTomas Henzl <thenzl@redhat.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 6c197093
...@@ -1104,18 +1104,16 @@ _base_is_controller_msix_enabled(struct MPT3SAS_ADAPTER *ioc) ...@@ -1104,18 +1104,16 @@ _base_is_controller_msix_enabled(struct MPT3SAS_ADAPTER *ioc)
} }
/** /**
* mpt3sas_base_flush_reply_queues - flushing the MSIX reply queues * mpt3sas_base_sync_reply_irqs - flush pending MSIX interrupts
* @ioc: per adapter object * @ioc: per adapter object
* Context: ISR conext * Context: non ISR conext
* *
* Called when a Task Management request has completed. We want * Called when a Task Management request has completed.
* to flush the other reply queues so all the outstanding IO has been
* completed back to OS before we process the TM completetion.
* *
* Return nothing. * Return nothing.
*/ */
void void
mpt3sas_base_flush_reply_queues(struct MPT3SAS_ADAPTER *ioc) mpt3sas_base_sync_reply_irqs(struct MPT3SAS_ADAPTER *ioc)
{ {
struct adapter_reply_queue *reply_q; struct adapter_reply_queue *reply_q;
...@@ -1126,12 +1124,13 @@ mpt3sas_base_flush_reply_queues(struct MPT3SAS_ADAPTER *ioc) ...@@ -1126,12 +1124,13 @@ mpt3sas_base_flush_reply_queues(struct MPT3SAS_ADAPTER *ioc)
return; return;
list_for_each_entry(reply_q, &ioc->reply_queue_list, list) { list_for_each_entry(reply_q, &ioc->reply_queue_list, list) {
if (ioc->shost_recovery) if (ioc->shost_recovery || ioc->remove_host ||
ioc->pci_error_recovery)
return; return;
/* TMs are on msix_index == 0 */ /* TMs are on msix_index == 0 */
if (reply_q->msix_index == 0) if (reply_q->msix_index == 0)
continue; continue;
_base_interrupt(reply_q->vector, (void *)reply_q); synchronize_irq(reply_q->vector);
} }
} }
......
...@@ -1236,7 +1236,8 @@ void *mpt3sas_base_get_msg_frame(struct MPT3SAS_ADAPTER *ioc, u16 smid); ...@@ -1236,7 +1236,8 @@ void *mpt3sas_base_get_msg_frame(struct MPT3SAS_ADAPTER *ioc, u16 smid);
void *mpt3sas_base_get_sense_buffer(struct MPT3SAS_ADAPTER *ioc, u16 smid); void *mpt3sas_base_get_sense_buffer(struct MPT3SAS_ADAPTER *ioc, u16 smid);
__le32 mpt3sas_base_get_sense_buffer_dma(struct MPT3SAS_ADAPTER *ioc, __le32 mpt3sas_base_get_sense_buffer_dma(struct MPT3SAS_ADAPTER *ioc,
u16 smid); u16 smid);
void mpt3sas_base_flush_reply_queues(struct MPT3SAS_ADAPTER *ioc);
void mpt3sas_base_sync_reply_irqs(struct MPT3SAS_ADAPTER *ioc);
/* hi-priority queue */ /* hi-priority queue */
u16 mpt3sas_base_get_smid_hpr(struct MPT3SAS_ADAPTER *ioc, u8 cb_idx); u16 mpt3sas_base_get_smid_hpr(struct MPT3SAS_ADAPTER *ioc, u8 cb_idx);
......
...@@ -2124,7 +2124,6 @@ _scsih_tm_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) ...@@ -2124,7 +2124,6 @@ _scsih_tm_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
return 1; return 1;
if (ioc->tm_cmds.smid != smid) if (ioc->tm_cmds.smid != smid)
return 1; return 1;
mpt3sas_base_flush_reply_queues(ioc);
ioc->tm_cmds.status |= MPT3_CMD_COMPLETE; ioc->tm_cmds.status |= MPT3_CMD_COMPLETE;
mpi_reply = mpt3sas_base_get_reply_virt_addr(ioc, reply); mpi_reply = mpt3sas_base_get_reply_virt_addr(ioc, reply);
if (mpi_reply) { if (mpi_reply) {
...@@ -2309,6 +2308,9 @@ mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle, uint channel, ...@@ -2309,6 +2308,9 @@ mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle, uint channel,
} }
} }
/* sync IRQs in case those were busy during flush. */
mpt3sas_base_sync_reply_irqs(ioc);
if (ioc->tm_cmds.status & MPT3_CMD_REPLY_VALID) { if (ioc->tm_cmds.status & MPT3_CMD_REPLY_VALID) {
mpt3sas_trigger_master(ioc, MASTER_TRIGGER_TASK_MANAGMENT); mpt3sas_trigger_master(ioc, MASTER_TRIGGER_TASK_MANAGMENT);
mpi_reply = ioc->tm_cmds.reply; mpi_reply = ioc->tm_cmds.reply;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment