diff options
author | Jayamohan Kallickal <jayamohank@gmail.com> | 2013-09-28 18:35:43 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2013-10-25 04:58:05 -0400 |
commit | 92665a6628902246368494972a38d84b1b091cb8 (patch) | |
tree | 68e275270496fa6a3b04eadf0f601cefdd7bb640 /drivers/scsi/be2iscsi | |
parent | 8f09a3b97804924bf7787161e4ad5c273d12b11e (diff) |
[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: John Soni Jose <sony.john-n@emulex.com>
Signed-off-by: Jayamohan Kallickal <jayamohan.kallickal@emulex.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/be2iscsi')
-rw-r--r-- | drivers/scsi/be2iscsi/be.h | 2 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_cmds.c | 48 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_main.c | 5 |
3 files changed, 34 insertions, 21 deletions
diff --git a/drivers/scsi/be2iscsi/be.h b/drivers/scsi/be2iscsi/be.h index 777e7c0bbb4b..2e28f6c419fe 100644 --- a/drivers/scsi/be2iscsi/be.h +++ b/drivers/scsi/be2iscsi/be.h | |||
@@ -128,7 +128,7 @@ struct be_ctrl_info { | |||
128 | 128 | ||
129 | #define PAGE_SHIFT_4K 12 | 129 | #define PAGE_SHIFT_4K 12 |
130 | #define PAGE_SIZE_4K (1 << PAGE_SHIFT_4K) | 130 | #define PAGE_SIZE_4K (1 << PAGE_SHIFT_4K) |
131 | #define mcc_timeout 120000 /* 5s timeout */ | 131 | #define mcc_timeout 120000 /* 12s timeout */ |
132 | 132 | ||
133 | /* Returns number of pages spanned by the data starting at the given addr */ | 133 | /* Returns number of pages spanned by the data starting at the given addr */ |
134 | #define PAGES_4K_SPANNED(_address, size) \ | 134 | #define PAGES_4K_SPANNED(_address, size) \ |
diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c index f7788e59c3f2..df03067abded 100644 --- a/drivers/scsi/be2iscsi/be_cmds.c +++ b/drivers/scsi/be2iscsi/be_cmds.c | |||
@@ -490,33 +490,47 @@ int be_mcc_notify_wait(struct beiscsi_hba *phba) | |||
490 | **/ | 490 | **/ |
491 | static int be_mbox_db_ready_wait(struct be_ctrl_info *ctrl) | 491 | static int be_mbox_db_ready_wait(struct be_ctrl_info *ctrl) |
492 | { | 492 | { |
493 | #define BEISCSI_MBX_RDY_BIT_TIMEOUT 4000 /* 4sec */ | ||
493 | void __iomem *db = ctrl->db + MPU_MAILBOX_DB_OFFSET; | 494 | void __iomem *db = ctrl->db + MPU_MAILBOX_DB_OFFSET; |
494 | struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev); | 495 | struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev); |
495 | uint32_t wait = 0; | 496 | unsigned long timeout; |
497 | bool read_flag = false; | ||
498 | int ret = 0, i; | ||
496 | u32 ready; | 499 | u32 ready; |
500 | DECLARE_WAIT_QUEUE_HEAD_ONSTACK(rdybit_check_q); | ||
497 | 501 | ||
498 | do { | 502 | if (beiscsi_error(phba)) |
503 | return -EIO; | ||
499 | 504 | ||
500 | if (beiscsi_error(phba)) | 505 | timeout = jiffies + (HZ * 110); |
501 | return -EIO; | ||
502 | 506 | ||
503 | ready = ioread32(db) & MPU_MAILBOX_DB_RDY_MASK; | 507 | do { |
504 | if (ready) | 508 | for (i = 0; i < BEISCSI_MBX_RDY_BIT_TIMEOUT; i++) { |
505 | break; | 509 | ready = ioread32(db) & MPU_MAILBOX_DB_RDY_MASK; |
510 | if (ready) { | ||
511 | read_flag = true; | ||
512 | break; | ||
513 | } | ||
514 | mdelay(1); | ||
515 | } | ||
506 | 516 | ||
507 | if (wait > BEISCSI_HOST_MBX_TIMEOUT) { | 517 | if (!read_flag) { |
508 | beiscsi_log(phba, KERN_ERR, | 518 | wait_event_timeout(rdybit_check_q, |
509 | BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX, | 519 | (read_flag != true), |
510 | "BC_%d : FW Timed Out\n"); | 520 | HZ * 5); |
521 | } | ||
522 | } while ((time_before(jiffies, timeout)) && !read_flag); | ||
523 | |||
524 | if (!read_flag) { | ||
525 | beiscsi_log(phba, KERN_ERR, | ||
526 | BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX, | ||
527 | "BC_%d : FW Timed Out\n"); | ||
511 | phba->fw_timeout = true; | 528 | phba->fw_timeout = true; |
512 | beiscsi_ue_detect(phba); | 529 | beiscsi_ue_detect(phba); |
513 | return -EBUSY; | 530 | ret = -EBUSY; |
514 | } | 531 | } |
515 | 532 | ||
516 | mdelay(1); | 533 | return ret; |
517 | wait++; | ||
518 | } while (true); | ||
519 | return 0; | ||
520 | } | 534 | } |
521 | 535 | ||
522 | /* | 536 | /* |
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c index 991858262b72..6ad36af4654a 100644 --- a/drivers/scsi/be2iscsi/be_main.c +++ b/drivers/scsi/be2iscsi/be_main.c | |||
@@ -5002,14 +5002,13 @@ static int beiscsi_dev_probe(struct pci_dev *pcidev, | |||
5002 | ret = beiscsi_cmd_reset_function(phba); | 5002 | ret = beiscsi_cmd_reset_function(phba); |
5003 | if (ret) { | 5003 | if (ret) { |
5004 | beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, | 5004 | beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, |
5005 | "BM_%d : Reset Failed. Aborting Crashdump\n"); | 5005 | "BM_%d : Reset Failed\n"); |
5006 | goto hba_free; | 5006 | goto hba_free; |
5007 | } | 5007 | } |
5008 | ret = be_chk_reset_complete(phba); | 5008 | ret = be_chk_reset_complete(phba); |
5009 | if (ret) { | 5009 | if (ret) { |
5010 | beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, | 5010 | beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, |
5011 | "BM_%d : Failed to get out of reset." | 5011 | "BM_%d : Failed to get out of reset.\n"); |
5012 | "Aborting Crashdump\n"); | ||
5013 | goto hba_free; | 5012 | goto hba_free; |
5014 | } | 5013 | } |
5015 | 5014 | ||