[SCSI] be2iscsi : Fix the NOP-In handling code path
authorJayamohan Kallickal <jayamohank@gmail.com>
Sat, 6 Apr 2013 03:38:31 +0000 (20:38 -0700)
committerJames Bottomley <JBottomley@Parallels.com>
Thu, 2 May 2013 15:14:07 +0000 (08:14 -0700)
When target send a NOP-IN with valid TTT, driver issues a NOP-OUT
and the task was not freed from driver. The task list available for
the session used to run out, and as no more task list were available
no more iSCSI commands were exchanged on that session.
This patches fixed the issue, by calling iscsi_put_task.

Signed-off-by: Minh Tran <minhduc.tran@emulex.com>
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_iscsi.c
drivers/scsi/be2iscsi/be_main.c
drivers/scsi/be2iscsi/be_main.h

index dd5beff92c6156dd4ca84e25c3d06a1660bccfe6..5b64fd4b3c35576ddcad24888df5d6123187dd67 100644 (file)
@@ -1005,7 +1005,8 @@ static void beiscsi_free_ep(struct beiscsi_endpoint *beiscsi_ep)
 
        beiscsi_conn = beiscsi_ep->conn;
        if (beiscsi_conn->login_in_progress) {
-               beiscsi_free_mgmt_task_handles(beiscsi_conn);
+               beiscsi_free_mgmt_task_handles(beiscsi_conn,
+                                              beiscsi_conn->task);
                beiscsi_conn->login_in_progress = 0;
        }
 }
index ff89b4cc363417923cb4f2ead9d9641edeea3ad1..a60a43d4d9479bcaa84172f221d717ee4e20c3bb 100644 (file)
@@ -1367,8 +1367,6 @@ hwi_complete_drvr_msgs(struct beiscsi_conn *beiscsi_conn,
        struct hwi_controller *phwi_ctrlr;
        struct iscsi_task *task;
        struct beiscsi_io_task *io_task;
-       struct iscsi_conn *conn = beiscsi_conn->conn;
-       struct iscsi_session *session = conn->session;
        uint16_t wrb_index, cid;
 
        phwi_ctrlr = phba->phwi_ctrlr;
@@ -1390,12 +1388,8 @@ hwi_complete_drvr_msgs(struct beiscsi_conn *beiscsi_conn,
        task = pwrb_handle->pio_handle;
 
        io_task = task->dd_data;
-       spin_lock_bh(&phba->mgmt_sgl_lock);
-       free_mgmt_sgl_handle(phba, io_task->psgl_handle);
-       spin_unlock_bh(&phba->mgmt_sgl_lock);
-       spin_lock_bh(&session->lock);
-       free_wrb_handle(phba, pwrb_context, pwrb_handle);
-       spin_unlock_bh(&session->lock);
+       memset(io_task->pwrb_handle->pwrb, 0, sizeof(struct iscsi_wrb));
+       iscsi_put_task(task);
 }
 
 static void
@@ -4073,11 +4067,13 @@ static void beiscsi_clean_port(struct beiscsi_hba *phba)
 /**
  * beiscsi_free_mgmt_task_handles()- Free driver CXN resources
  * @beiscsi_conn: ptr to the conn to be cleaned up
+ * @task: ptr to iscsi_task resource to be freed.
  *
  * Free driver mgmt resources binded to CXN.
  **/
 void
-beiscsi_free_mgmt_task_handles(struct beiscsi_conn *beiscsi_conn)
+beiscsi_free_mgmt_task_handles(struct beiscsi_conn *beiscsi_conn,
+                               struct iscsi_task *task)
 {
        struct beiscsi_io_task *io_task;
        struct beiscsi_hba *phba = beiscsi_conn->phba;
@@ -4088,7 +4084,7 @@ beiscsi_free_mgmt_task_handles(struct beiscsi_conn *beiscsi_conn)
        pwrb_context = &phwi_ctrlr->wrb_context
                       [beiscsi_conn->beiscsi_conn_cid
                       - phba->fw_config.iscsi_cid_start];
-       io_task = beiscsi_conn->task->dd_data;
+       io_task = task->dd_data;
 
        if (io_task->pwrb_handle) {
                memset(io_task->pwrb_handle->pwrb, 0,
@@ -4102,8 +4098,8 @@ beiscsi_free_mgmt_task_handles(struct beiscsi_conn *beiscsi_conn)
                spin_lock_bh(&phba->mgmt_sgl_lock);
                free_mgmt_sgl_handle(phba,
                                     io_task->psgl_handle);
-               spin_unlock_bh(&phba->mgmt_sgl_lock);
                io_task->psgl_handle = NULL;
+               spin_unlock_bh(&phba->mgmt_sgl_lock);
        }
 
        if (io_task->mtask_addr)
@@ -4153,7 +4149,7 @@ static void beiscsi_cleanup_task(struct iscsi_task *task)
                }
        } else {
                if (!beiscsi_conn->login_in_progress)
-                       beiscsi_free_mgmt_task_handles(beiscsi_conn);
+                       beiscsi_free_mgmt_task_handles(beiscsi_conn, task);
        }
 }
 
@@ -4381,7 +4377,6 @@ int beiscsi_iotask_v2(struct iscsi_task *task, struct scatterlist *sg,
        unsigned int doorbell = 0;
 
        pwrb = io_task->pwrb_handle->pwrb;
-       memset(pwrb, 0, sizeof(*pwrb));
 
        io_task->cmd_bhs->iscsi_hdr.exp_statsn = 0;
        io_task->bhs_len = sizeof(struct be_cmd_bhs);
index 3c5df9219b032ba7c832c98f3468e7e9e6f462fe..ac4ef34d80b13b707c9adb6ab7f7a6aacb4805f3 100644 (file)
@@ -753,7 +753,8 @@ void
 free_mgmt_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle);
 
 void beiscsi_process_all_cqs(struct work_struct *work);
-void beiscsi_free_mgmt_task_handles(struct beiscsi_conn *beiscsi_conn);
+void beiscsi_free_mgmt_task_handles(struct beiscsi_conn *beiscsi_conn,
+                                    struct iscsi_task *task);
 
 static inline bool beiscsi_error(struct beiscsi_hba *phba)
 {