]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
be2iscsi:Freeing of WRB and SGL Handle in cleanup task
authorroot <root@localhost.localdomain>
Wed, 2 May 2012 14:09:28 +0000 (19:39 +0530)
committerMaxim Uvarov <maxim.uvarov@oracle.com>
Fri, 11 May 2012 00:08:48 +0000 (17:08 -0700)
 The WRB and SGL Handle allocated for Login task were not freed
 back to the pool after the login process was done. This code
 releases the WRB and SGL Handle after the login process.

 v2:
 - Fix up locking so bh calls are not done when not needed.
 - Make beiscsi_cleanup_task static.

Signed-off-by: Jayamohan Kallickal <jayamohan.kallickal@emulex.com>
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: root <root@localhost.(none)>
drivers/scsi/be2iscsi/be_main.c

index 169c6d442df2cb2f2f9296af226679d499818fc1..ccf92fc20570f83edc5233a0657246058c27a15d 100644 (file)
@@ -1251,9 +1251,9 @@ hwi_complete_drvr_msgs(struct beiscsi_conn *beiscsi_conn,
        task = pwrb_handle->pio_handle;
 
        io_task = task->dd_data;
-       spin_lock(&phba->mgmt_sgl_lock);
+       spin_lock_bh(&phba->mgmt_sgl_lock);
        free_mgmt_sgl_handle(phba, io_task->psgl_handle);
-       spin_unlock(&phba->mgmt_sgl_lock);
+       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);
@@ -3692,6 +3692,57 @@ static void beiscsi_clean_port(struct beiscsi_hba *phba)
        kfree(phba->ep_array);
 }
 
+static void beiscsi_cleanup_task(struct iscsi_task *task)
+{
+       struct beiscsi_io_task *io_task = task->dd_data;
+       struct iscsi_conn *conn = task->conn;
+       struct beiscsi_conn *beiscsi_conn = conn->dd_data;
+       struct beiscsi_hba *phba = beiscsi_conn->phba;
+       struct beiscsi_session *beiscsi_sess = beiscsi_conn->beiscsi_sess;
+       struct hwi_wrb_context *pwrb_context;
+       struct hwi_controller *phwi_ctrlr;
+
+       phwi_ctrlr = phba->phwi_ctrlr;
+       pwrb_context = &phwi_ctrlr->wrb_context[beiscsi_conn->beiscsi_conn_cid
+                       - phba->fw_config.iscsi_cid_start];
+
+       if (io_task->cmd_bhs) {
+               pci_pool_free(beiscsi_sess->bhs_pool, io_task->cmd_bhs,
+                             io_task->bhs_pa.u.a64.address);
+               io_task->cmd_bhs = NULL;
+       }
+
+       if (task->sc) {
+               if (io_task->pwrb_handle) {
+                       free_wrb_handle(phba, pwrb_context,
+                                       io_task->pwrb_handle);
+                       io_task->pwrb_handle = NULL;
+               }
+
+               if (io_task->psgl_handle) {
+                       spin_lock(&phba->io_sgl_lock);
+                       free_io_sgl_handle(phba, io_task->psgl_handle);
+                       spin_unlock(&phba->io_sgl_lock);
+                       io_task->psgl_handle = NULL;
+               }
+       } else {
+               if (!beiscsi_conn->login_in_progress) {
+                       if (io_task->pwrb_handle) {
+                               free_wrb_handle(phba, pwrb_context,
+                                               io_task->pwrb_handle);
+                               io_task->pwrb_handle = NULL;
+                       }
+                       if (io_task->psgl_handle) {
+                               spin_lock(&phba->mgmt_sgl_lock);
+                               free_mgmt_sgl_handle(phba,
+                                                    io_task->psgl_handle);
+                               spin_unlock(&phba->mgmt_sgl_lock);
+                               io_task->psgl_handle = NULL;
+                       }
+               }
+       }
+}
+
 void
 beiscsi_offload_connection(struct beiscsi_conn *beiscsi_conn,
                           struct beiscsi_offload_params *params)
@@ -3700,12 +3751,19 @@ beiscsi_offload_connection(struct beiscsi_conn *beiscsi_conn,
        struct iscsi_target_context_update_wrb *pwrb = NULL;
        struct be_mem_descriptor *mem_descr;
        struct beiscsi_hba *phba = beiscsi_conn->phba;
+       struct iscsi_task *task = beiscsi_conn->task;
+       struct iscsi_session *session = task->conn->session;
        u32 doorbell = 0;
 
        /*
         * We can always use 0 here because it is reserved by libiscsi for
         * login/startup related tasks.
         */
+       beiscsi_conn->login_in_progress = 0;
+       spin_lock_bh(&session->lock);
+       beiscsi_cleanup_task(task);
+       spin_unlock_bh(&session->lock);
+
        pwrb_handle = alloc_wrb_handle(phba, (beiscsi_conn->beiscsi_conn_cid -
                                       phba->fw_config.iscsi_cid_start));
        pwrb = (struct iscsi_target_context_update_wrb *)pwrb_handle->pwrb;
@@ -3861,6 +3919,7 @@ static int beiscsi_alloc_pdu(struct iscsi_task *task, uint8_t opcode)
                                io_task->pwrb_handle =
                                                beiscsi_conn->plogin_wrb_handle;
                        }
+                       beiscsi_conn->task = task;
                } else {
                        spin_lock(&phba->mgmt_sgl_lock);
                        io_task->psgl_handle = alloc_mgmt_sgl_handle(phba);
@@ -3903,53 +3962,11 @@ free_hndls:
        io_task->pwrb_handle = NULL;
        pci_pool_free(beiscsi_sess->bhs_pool, io_task->cmd_bhs,
                      io_task->bhs_pa.u.a64.address);
+       io_task->cmd_bhs = NULL;
        SE_DEBUG(DBG_LVL_1, "Alloc of SGL_ICD Failed\n");
        return -ENOMEM;
 }
 
-static void beiscsi_cleanup_task(struct iscsi_task *task)
-{
-       struct beiscsi_io_task *io_task = task->dd_data;
-       struct iscsi_conn *conn = task->conn;
-       struct beiscsi_conn *beiscsi_conn = conn->dd_data;
-       struct beiscsi_hba *phba = beiscsi_conn->phba;
-       struct beiscsi_session *beiscsi_sess = beiscsi_conn->beiscsi_sess;
-       struct hwi_wrb_context *pwrb_context;
-       struct hwi_controller *phwi_ctrlr;
-
-       phwi_ctrlr = phba->phwi_ctrlr;
-       pwrb_context = &phwi_ctrlr->wrb_context[beiscsi_conn->beiscsi_conn_cid
-                       - phba->fw_config.iscsi_cid_start];
-       if (io_task->pwrb_handle) {
-               free_wrb_handle(phba, pwrb_context, io_task->pwrb_handle);
-               io_task->pwrb_handle = NULL;
-       }
-
-       if (io_task->cmd_bhs) {
-               pci_pool_free(beiscsi_sess->bhs_pool, io_task->cmd_bhs,
-                             io_task->bhs_pa.u.a64.address);
-       }
-
-       if (task->sc) {
-               if (io_task->psgl_handle) {
-                       spin_lock(&phba->io_sgl_lock);
-                       free_io_sgl_handle(phba, io_task->psgl_handle);
-                       spin_unlock(&phba->io_sgl_lock);
-                       io_task->psgl_handle = NULL;
-               }
-       } else {
-               if (task->hdr &&
-                  ((task->hdr->opcode & ISCSI_OPCODE_MASK) == ISCSI_OP_LOGIN))
-                       return;
-               if (io_task->psgl_handle) {
-                       spin_lock(&phba->mgmt_sgl_lock);
-                       free_mgmt_sgl_handle(phba, io_task->psgl_handle);
-                       spin_unlock(&phba->mgmt_sgl_lock);
-                       io_task->psgl_handle = NULL;
-               }
-       }
-}
-
 static int beiscsi_iotask(struct iscsi_task *task, struct scatterlist *sg,
                          unsigned int num_sg, unsigned int xferlen,
                          unsigned int writedir)