Commit 92665a66 authored by Jayamohan Kallickal's avatar Jayamohan Kallickal Committed by James Bottomley

[SCSI] be2iscsi: Fix soft lock up issue during UE or if FW taking time to respond

The timeout set in MBX_CMD is 100sec and the ready bit checking in BMBX
mode is done for 4sec. After 4sec the task is scheduled out for 5 secs
to avoid kernel soft lockup stack trace. The loop of 4sec ready bit check
and then schedule out is done until the following conditon occur
- The Ready Bit is Set
- The timeout set in MBX_CMD expires
Signed-off-by: default avatarJohn Soni Jose <sony.john-n@emulex.com>
Signed-off-by: default avatarJayamohan Kallickal <jayamohan.kallickal@emulex.com>
Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
parent 8f09a3b9
...@@ -128,7 +128,7 @@ struct be_ctrl_info { ...@@ -128,7 +128,7 @@ struct be_ctrl_info {
#define PAGE_SHIFT_4K 12 #define PAGE_SHIFT_4K 12
#define PAGE_SIZE_4K (1 << PAGE_SHIFT_4K) #define PAGE_SIZE_4K (1 << PAGE_SHIFT_4K)
#define mcc_timeout 120000 /* 5s timeout */ #define mcc_timeout 120000 /* 12s timeout */
/* Returns number of pages spanned by the data starting at the given addr */ /* Returns number of pages spanned by the data starting at the given addr */
#define PAGES_4K_SPANNED(_address, size) \ #define PAGES_4K_SPANNED(_address, size) \
......
...@@ -490,33 +490,47 @@ int be_mcc_notify_wait(struct beiscsi_hba *phba) ...@@ -490,33 +490,47 @@ int be_mcc_notify_wait(struct beiscsi_hba *phba)
**/ **/
static int be_mbox_db_ready_wait(struct be_ctrl_info *ctrl) static int be_mbox_db_ready_wait(struct be_ctrl_info *ctrl)
{ {
#define BEISCSI_MBX_RDY_BIT_TIMEOUT 4000 /* 4sec */
void __iomem *db = ctrl->db + MPU_MAILBOX_DB_OFFSET; void __iomem *db = ctrl->db + MPU_MAILBOX_DB_OFFSET;
struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev); struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev);
uint32_t wait = 0; unsigned long timeout;
bool read_flag = false;
int ret = 0, i;
u32 ready; u32 ready;
DECLARE_WAIT_QUEUE_HEAD_ONSTACK(rdybit_check_q);
do {
if (beiscsi_error(phba)) if (beiscsi_error(phba))
return -EIO; return -EIO;
timeout = jiffies + (HZ * 110);
do {
for (i = 0; i < BEISCSI_MBX_RDY_BIT_TIMEOUT; i++) {
ready = ioread32(db) & MPU_MAILBOX_DB_RDY_MASK; ready = ioread32(db) & MPU_MAILBOX_DB_RDY_MASK;
if (ready) if (ready) {
read_flag = true;
break; break;
}
mdelay(1);
}
if (!read_flag) {
wait_event_timeout(rdybit_check_q,
(read_flag != true),
HZ * 5);
}
} while ((time_before(jiffies, timeout)) && !read_flag);
if (wait > BEISCSI_HOST_MBX_TIMEOUT) { if (!read_flag) {
beiscsi_log(phba, KERN_ERR, beiscsi_log(phba, KERN_ERR,
BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX, BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
"BC_%d : FW Timed Out\n"); "BC_%d : FW Timed Out\n");
phba->fw_timeout = true; phba->fw_timeout = true;
beiscsi_ue_detect(phba); beiscsi_ue_detect(phba);
return -EBUSY; ret = -EBUSY;
} }
mdelay(1); return ret;
wait++;
} while (true);
return 0;
} }
/* /*
......
...@@ -5002,14 +5002,13 @@ static int beiscsi_dev_probe(struct pci_dev *pcidev, ...@@ -5002,14 +5002,13 @@ static int beiscsi_dev_probe(struct pci_dev *pcidev,
ret = beiscsi_cmd_reset_function(phba); ret = beiscsi_cmd_reset_function(phba);
if (ret) { if (ret) {
beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
"BM_%d : Reset Failed. Aborting Crashdump\n"); "BM_%d : Reset Failed\n");
goto hba_free; goto hba_free;
} }
ret = be_chk_reset_complete(phba); ret = be_chk_reset_complete(phba);
if (ret) { if (ret) {
beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
"BM_%d : Failed to get out of reset." "BM_%d : Failed to get out of reset.\n");
"Aborting Crashdump\n");
goto hba_free; goto hba_free;
} }
......
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