Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

[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
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -128,7 +128,7 @@ struct be_ctrl_info {

#define PAGE_SHIFT_4K 12
#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 */
#define PAGES_4K_SPANNED(_address, size)				\
+31 −17
Original line number Diff line number Diff line
@@ -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)
{
#define BEISCSI_MBX_RDY_BIT_TIMEOUT	4000	/* 4sec */
	void __iomem *db = ctrl->db + MPU_MAILBOX_DB_OFFSET;
	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;

	do {
	DECLARE_WAIT_QUEUE_HEAD_ONSTACK(rdybit_check_q);

	if (beiscsi_error(phba))
		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;
		if (ready)
			if (ready) {
				read_flag = true;
				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_CONFIG | BEISCSI_LOG_MBOX,
			    "BC_%d : FW Timed Out\n");
			phba->fw_timeout = true;
			beiscsi_ue_detect(phba);
			return -EBUSY;
			ret = -EBUSY;
	}

		mdelay(1);
		wait++;
	} while (true);
	return 0;
	return ret;
}

/*
+2 −3
Original line number Diff line number Diff line
@@ -5002,14 +5002,13 @@ static int beiscsi_dev_probe(struct pci_dev *pcidev,
	ret = beiscsi_cmd_reset_function(phba);
	if (ret) {
		beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
			    "BM_%d : Reset Failed. Aborting Crashdump\n");
			    "BM_%d : Reset Failed\n");
		goto hba_free;
	}
	ret = be_chk_reset_complete(phba);
	if (ret) {
		beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
			    "BM_%d : Failed to get out of reset."
			    "Aborting Crashdump\n");
			    "BM_%d : Failed to get out of reset.\n");
		goto hba_free;
	}