summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Smart <jsmart2021@gmail.com>2018-03-05 12:04:07 -0800
committerMartin K. Petersen <martin.petersen@oracle.com>2018-03-12 21:55:24 -0400
commite29d74f8eb1450b0b6c4736210d76cb56ef40e1d (patch)
treef449dc44b6d2df5d62457dbf84ef6e8a03836f53
parenta3da825b499f495f959052b848e893550ddaf626 (diff)
scsi: lpfc: Fix mailbox wait for POST_SGL mbox command
POST_SGL_PAGES mailbox command failed with status (timeout). wait_event_interruptible_timeout when called from mailbox wait interface, gets interrupted, and will randomly fail. Behavior seems very specific to 1 particular server type. Fix by changing from wait_event_interruptible_timeout to wait_for_completion_timeout. Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com> Signed-off-by: James Smart <james.smart@broadcom.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c34
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.h1
2 files changed, 13 insertions, 22 deletions
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 7999a40e1370..1a9083adef1f 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -2388,18 +2388,18 @@ lpfc_sli_chk_mbx_command(uint8_t mbxCommand)
void
lpfc_sli_wake_mbox_wait(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)
{
- wait_queue_head_t *pdone_q;
unsigned long drvr_flag;
+ struct completion *pmbox_done;
/*
- * If pdone_q is empty, the driver thread gave up waiting and
+ * If pmbox_done is empty, the driver thread gave up waiting and
* continued running.
*/
pmboxq->mbox_flag |= LPFC_MBX_WAKE;
spin_lock_irqsave(&phba->hbalock, drvr_flag);
- pdone_q = (wait_queue_head_t *) pmboxq->context1;
- if (pdone_q)
- wake_up_interruptible(pdone_q);
+ pmbox_done = (struct completion *)pmboxq->context3;
+ if (pmbox_done)
+ complete(pmbox_done);
spin_unlock_irqrestore(&phba->hbalock, drvr_flag);
return;
}
@@ -11665,31 +11665,25 @@ int
lpfc_sli_issue_mbox_wait(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq,
uint32_t timeout)
{
- DECLARE_WAIT_QUEUE_HEAD_ONSTACK(done_q);
- MAILBOX_t *mb = NULL;
+ struct completion mbox_done;
int retval;
unsigned long flag;
- /* The caller might set context1 for extended buffer */
- if (pmboxq->context1)
- mb = (MAILBOX_t *)pmboxq->context1;
-
pmboxq->mbox_flag &= ~LPFC_MBX_WAKE;
/* setup wake call as IOCB callback */
pmboxq->mbox_cmpl = lpfc_sli_wake_mbox_wait;
- /* setup context field to pass wait_queue pointer to wake function */
- pmboxq->context1 = &done_q;
+ /* setup context3 field to pass wait_queue pointer to wake function */
+ init_completion(&mbox_done);
+ pmboxq->context3 = &mbox_done;
/* now issue the command */
retval = lpfc_sli_issue_mbox(phba, pmboxq, MBX_NOWAIT);
if (retval == MBX_BUSY || retval == MBX_SUCCESS) {
- wait_event_interruptible_timeout(done_q,
- pmboxq->mbox_flag & LPFC_MBX_WAKE,
- msecs_to_jiffies(timeout * 1000));
+ wait_for_completion_timeout(&mbox_done,
+ msecs_to_jiffies(timeout * 1000));
spin_lock_irqsave(&phba->hbalock, flag);
- /* restore the possible extended buffer for free resource */
- pmboxq->context1 = (uint8_t *)mb;
+ pmboxq->context3 = NULL;
/*
* if LPFC_MBX_WAKE flag is set the mailbox is completed
* else do not free the resources.
@@ -11701,11 +11695,7 @@ lpfc_sli_issue_mbox_wait(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq,
pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
}
spin_unlock_irqrestore(&phba->hbalock, flag);
- } else {
- /* restore the possible extended buffer for free resource */
- pmboxq->context1 = (uint8_t *)mb;
}
-
return retval;
}
diff --git a/drivers/scsi/lpfc/lpfc_sli.h b/drivers/scsi/lpfc/lpfc_sli.h
index ad7b2e0a2018..431754195505 100644
--- a/drivers/scsi/lpfc/lpfc_sli.h
+++ b/drivers/scsi/lpfc/lpfc_sli.h
@@ -147,6 +147,7 @@ typedef struct lpfcMboxq {
struct lpfc_vport *vport;/* virtual port pointer */
void *context1; /* caller context information */
void *context2; /* caller context information */
+ void *context3;
void (*mbox_cmpl) (struct lpfc_hba *, struct lpfcMboxq *);
uint8_t mbox_flag;