[SCSI] be2iscsi: Fix the session cleanup when reboot/shutdown happens
authorJayamohan Kallickal <jayamohan.kallickal@emulex.com>
Wed, 29 Jan 2014 07:16:43 +0000 (02:16 -0500)
committerJames Bottomley <JBottomley@Parallels.com>
Sat, 15 Mar 2014 17:19:11 +0000 (10:19 -0700)
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: John Soni Jose <sony.john-n@emulex.com>
Signed-off-by: Jayamohan Kallickal <jayamohan.kallickal@emulex.com>
Reviewed-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
drivers/scsi/be2iscsi/be.h
drivers/scsi/be2iscsi/be_cmds.c
drivers/scsi/be2iscsi/be_cmds.h
drivers/scsi/be2iscsi/be_iscsi.c
drivers/scsi/be2iscsi/be_main.c
drivers/scsi/be2iscsi/be_main.h

index 23c73fe426484534a3c53efbc84a546fe62a50af..1bfb0bd01198679fac77fb0c2c73a6e8d4ef57e9 100644 (file)
@@ -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)                               \
index 86d91f31a6a32284dde6a6b3d9f22ef34de6ab5f..1432ed5e9fc61f98874cb633c8c6f5506f85a2a9 100644 (file)
@@ -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);
 }
 
index 14c51e6f2445b79f969ecc6c9643cf02b40be42e..7cf7f99ee44238a874e193a09d24d13f69db759b 100644 (file)
@@ -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 */
index a7a210ef407c3e2945e250b39bf09a856dbd02af..a3df43324c9834816d20eab213f2b08465078f35 100644 (file)
@@ -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);
index 89c95f1537e8a32a550884ee9c1e80d9de6386f7..b1b6e74e0b7c4f2c5e73f466bd21f3a523d150ad 100644 (file)
@@ -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);
 }
index e02e14cedd5da1c071224477994a9ba18e504423..77f33a472845e2548a63e74f73c2ec59f98e6293 100644 (file)
 
 #define INVALID_SESS_HANDLE    0xFFFFFFFF
 
+/**
+ * Adapter States
+ **/
 #define BE_ADAPTER_LINK_UP     0x001
 #define BE_ADAPTER_LINK_DOWN   0x002
 #define BE_ADAPTER_PCI_ERR     0x004
+#define BE_ADAPTER_STATE_SHUTDOWN      0x008
+
 
 #define BEISCSI_CLEAN_UNLOAD   0x01
 #define BEISCSI_EEH_UNLOAD     0x02