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

Commit 9343be74 authored by Jayamohan Kallickal's avatar Jayamohan Kallickal Committed by James Bottomley
Browse files

[SCSI] be2iscsi: Fix the session cleanup when reboot/shutdown happens



In iSCSI Boot scenario, when machine is reboot/shutdown phase
the active sessions are not closed. Driver queue cleanup is
done as part of unload and device is disabled.

Sessions are still active, iSCSI commands are issued from
session which comes to driver, as driver cleanup and device
disabled there is kernel stack dump with errors.

Fix is invoking iscsi_session_failure with ISCSI_ERR_INVALID_HOST
on all the active sessions when shutdown routine is called.

Signed-off-by: default avatarJohn Soni Jose <sony.john-n@emulex.com>
Signed-off-by: default avatarJayamohan Kallickal <jayamohan.kallickal@emulex.com>
Reviewed-by: default avatarMike Christie <michaelc@cs.wisc.edu>
Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
parent e08b3c8b
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -139,6 +139,7 @@ struct be_ctrl_info {
#define PAGE_SHIFT_4K 12
#define PAGE_SIZE_4K (1 << PAGE_SHIFT_4K)
#define mcc_timeout		120000 /* 12s timeout */
#define BEISCSI_LOGOUT_SYNC_DELAY	250

/* Returns number of pages spanned by the data starting at the given addr */
#define PAGES_4K_SPANNED(_address, size)				\
+16 −1
Original line number Diff line number Diff line
@@ -400,8 +400,23 @@ static struct be_mcc_compl *be_mcc_compl_get(struct beiscsi_hba *phba)
	return NULL;
}

static void be2iscsi_fail_session(struct iscsi_cls_session *cls_session)
/**
 * be2iscsi_fail_session(): Closing session with appropriate error
 * @cls_session: ptr to session
 *
 * Depending on adapter state appropriate error flag is passed.
 **/
void be2iscsi_fail_session(struct iscsi_cls_session *cls_session)
{
	struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);
	struct beiscsi_hba *phba = iscsi_host_priv(shost);
	uint32_t iscsi_err_flag;

	if (phba->state & BE_ADAPTER_STATE_SHUTDOWN)
		iscsi_err_flag = ISCSI_ERR_INVALID_HOST;
	else
		iscsi_err_flag = ISCSI_ERR_CONN_FAILED;

	iscsi_session_failure(cls_session->dd_data, ISCSI_ERR_CONN_FAILED);
}

+1 −0
Original line number Diff line number Diff line
@@ -1318,4 +1318,5 @@ void be_wrb_hdr_prepare(struct be_mcc_wrb *wrb, int payload_len,
void be_cmd_hdr_prepare(struct be_cmd_req_hdr *req_hdr,
			u8 subsystem, u8 opcode, int cmd_len);

void be2iscsi_fail_session(struct iscsi_cls_session *cls_session);
#endif /* !BEISCSI_CMDS_H */
+1 −0
Original line number Diff line number Diff line
@@ -1361,6 +1361,7 @@ void beiscsi_ep_disconnect(struct iscsi_endpoint *ep)
	beiscsi_mccq_compl(phba, tag, NULL, NULL);
	beiscsi_close_conn(beiscsi_ep, tcp_upload_flag);
free_ep:
	msleep(BEISCSI_LOGOUT_SYNC_DELAY);
	beiscsi_free_ep(beiscsi_ep);
	beiscsi_unbind_conn_to_cid(phba, beiscsi_ep->ep_cid);
	iscsi_destroy_endpoint(beiscsi_ep->openiscsi_ep);
+2 −0
Original line number Diff line number Diff line
@@ -5301,6 +5301,8 @@ static void beiscsi_shutdown(struct pci_dev *pcidev)
		return;
	}

	phba->state = BE_ADAPTER_STATE_SHUTDOWN;
	iscsi_host_for_each_session(phba->shost, be2iscsi_fail_session);
	beiscsi_quiesce(phba, BEISCSI_CLEAN_UNLOAD);
	pci_disable_device(pcidev);
}
Loading