Commit e29d74f8 authored by James Smart's avatar James Smart Committed by Martin K. Petersen

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: default avatarDick Kennedy <dick.kennedy@broadcom.com>
Signed-off-by: default avatarJames Smart <james.smart@broadcom.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent a3da825b
...@@ -2388,18 +2388,18 @@ lpfc_sli_chk_mbx_command(uint8_t mbxCommand) ...@@ -2388,18 +2388,18 @@ lpfc_sli_chk_mbx_command(uint8_t mbxCommand)
void void
lpfc_sli_wake_mbox_wait(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq) lpfc_sli_wake_mbox_wait(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)
{ {
wait_queue_head_t *pdone_q;
unsigned long drvr_flag; 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. * continued running.
*/ */
pmboxq->mbox_flag |= LPFC_MBX_WAKE; pmboxq->mbox_flag |= LPFC_MBX_WAKE;
spin_lock_irqsave(&phba->hbalock, drvr_flag); spin_lock_irqsave(&phba->hbalock, drvr_flag);
pdone_q = (wait_queue_head_t *) pmboxq->context1; pmbox_done = (struct completion *)pmboxq->context3;
if (pdone_q) if (pmbox_done)
wake_up_interruptible(pdone_q); complete(pmbox_done);
spin_unlock_irqrestore(&phba->hbalock, drvr_flag); spin_unlock_irqrestore(&phba->hbalock, drvr_flag);
return; return;
} }
...@@ -11665,31 +11665,25 @@ int ...@@ -11665,31 +11665,25 @@ int
lpfc_sli_issue_mbox_wait(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq, lpfc_sli_issue_mbox_wait(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq,
uint32_t timeout) uint32_t timeout)
{ {
DECLARE_WAIT_QUEUE_HEAD_ONSTACK(done_q); struct completion mbox_done;
MAILBOX_t *mb = NULL;
int retval; int retval;
unsigned long flag; 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; pmboxq->mbox_flag &= ~LPFC_MBX_WAKE;
/* setup wake call as IOCB callback */ /* setup wake call as IOCB callback */
pmboxq->mbox_cmpl = lpfc_sli_wake_mbox_wait; 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 */ /* now issue the command */
retval = lpfc_sli_issue_mbox(phba, pmboxq, MBX_NOWAIT); retval = lpfc_sli_issue_mbox(phba, pmboxq, MBX_NOWAIT);
if (retval == MBX_BUSY || retval == MBX_SUCCESS) { if (retval == MBX_BUSY || retval == MBX_SUCCESS) {
wait_event_interruptible_timeout(done_q, wait_for_completion_timeout(&mbox_done,
pmboxq->mbox_flag & LPFC_MBX_WAKE,
msecs_to_jiffies(timeout * 1000)); msecs_to_jiffies(timeout * 1000));
spin_lock_irqsave(&phba->hbalock, flag); spin_lock_irqsave(&phba->hbalock, flag);
/* restore the possible extended buffer for free resource */ pmboxq->context3 = NULL;
pmboxq->context1 = (uint8_t *)mb;
/* /*
* if LPFC_MBX_WAKE flag is set the mailbox is completed * if LPFC_MBX_WAKE flag is set the mailbox is completed
* else do not free the resources. * else do not free the resources.
...@@ -11701,11 +11695,7 @@ lpfc_sli_issue_mbox_wait(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq, ...@@ -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; pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
} }
spin_unlock_irqrestore(&phba->hbalock, flag); spin_unlock_irqrestore(&phba->hbalock, flag);
} else {
/* restore the possible extended buffer for free resource */
pmboxq->context1 = (uint8_t *)mb;
} }
return retval; return retval;
} }
......
...@@ -147,6 +147,7 @@ typedef struct lpfcMboxq { ...@@ -147,6 +147,7 @@ typedef struct lpfcMboxq {
struct lpfc_vport *vport;/* virtual port pointer */ struct lpfc_vport *vport;/* virtual port pointer */
void *context1; /* caller context information */ void *context1; /* caller context information */
void *context2; /* caller context information */ void *context2; /* caller context information */
void *context3;
void (*mbox_cmpl) (struct lpfc_hba *, struct lpfcMboxq *); void (*mbox_cmpl) (struct lpfc_hba *, struct lpfcMboxq *);
uint8_t mbox_flag; uint8_t mbox_flag;
......
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