Skip to content

Commit

Permalink
[SCSI] be2iscsi: Freeing of WRB and SGL Handle in cleanup task
Browse files Browse the repository at this point in the history
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>
[various fixes]
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
  • Loading branch information
Mike Christie authored and James Bottomley committed Apr 25, 2012
1 parent 3ec7827 commit 1282ab7
Showing 1 changed file with 62 additions and 45 deletions.
107 changes: 62 additions & 45 deletions drivers/scsi/be2iscsi/be_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1252,9 +1252,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);
Expand Down Expand Up @@ -3693,6 +3693,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)
Expand All @@ -3701,12 +3752,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;
Expand Down Expand Up @@ -3862,6 +3920,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);
Expand Down Expand Up @@ -3904,53 +3963,11 @@ static int beiscsi_alloc_pdu(struct iscsi_task *task, uint8_t opcode)
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)
Expand Down

0 comments on commit 1282ab7

Please sign in to comment.