Skip to content

Commit

Permalink
[SCSI] be2iscsi: Fix memory leak in control path of driver
Browse files Browse the repository at this point in the history
In contorl path of the driver the task was mapped using
pci_map_single which was not unmapped when the completion
for the task had come.

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>
  • Loading branch information
John Soni Jose authored and James Bottomley committed Nov 27, 2012
1 parent 6763daa commit d629c47
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 10 deletions.
39 changes: 29 additions & 10 deletions drivers/scsi/be2iscsi/be_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2242,10 +2242,14 @@ hwi_write_sgl(struct iscsi_wrb *pwrb, struct scatterlist *sg,
AMAP_SET_BITS(struct amap_iscsi_sge, last_sge, psgl, 1);
}

/**
* hwi_write_buffer()- Populate the WRB with task info
* @pwrb: ptr to the WRB entry
* @task: iscsi task which is to be executed
**/
static void hwi_write_buffer(struct iscsi_wrb *pwrb, struct iscsi_task *task)
{
struct iscsi_sge *psgl;
unsigned long long addr;
struct beiscsi_io_task *io_task = task->dd_data;
struct beiscsi_conn *beiscsi_conn = io_task->conn;
struct beiscsi_hba *phba = beiscsi_conn->phba;
Expand All @@ -2259,24 +2263,27 @@ static void hwi_write_buffer(struct iscsi_wrb *pwrb, struct iscsi_task *task)
if (task->data) {
if (task->data_count) {
AMAP_SET_BITS(struct amap_iscsi_wrb, dsp, pwrb, 1);
addr = (u64) pci_map_single(phba->pcidev,
task->data,
task->data_count, 1);
io_task->mtask_addr = pci_map_single(phba->pcidev,
task->data,
task->data_count,
PCI_DMA_TODEVICE);

io_task->mtask_data_count = task->data_count;
} else {
AMAP_SET_BITS(struct amap_iscsi_wrb, dsp, pwrb, 0);
addr = 0;
io_task->mtask_addr = 0;
}
AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_addr_lo, pwrb,
((u32)(addr & 0xFFFFFFFF)));
lower_32_bits(io_task->mtask_addr));
AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_addr_hi, pwrb,
((u32)(addr >> 32)));
upper_32_bits(io_task->mtask_addr));
AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_len, pwrb,
task->data_count);

AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_last, pwrb, 1);
} else {
AMAP_SET_BITS(struct amap_iscsi_wrb, dsp, pwrb, 0);
addr = 0;
io_task->mtask_addr = 0;
}

psgl = (struct iscsi_sge *)io_task->psgl_handle->pfrag;
Expand All @@ -2299,9 +2306,9 @@ static void hwi_write_buffer(struct iscsi_wrb *pwrb, struct iscsi_task *task)
psgl++;
if (task->data) {
AMAP_SET_BITS(struct amap_iscsi_sge, addr_lo, psgl,
((u32)(addr & 0xFFFFFFFF)));
lower_32_bits(io_task->mtask_addr));
AMAP_SET_BITS(struct amap_iscsi_sge, addr_hi, psgl,
((u32)(addr >> 32)));
upper_32_bits(io_task->mtask_addr));
}
AMAP_SET_BITS(struct amap_iscsi_sge, len, psgl, 0x106);
}
Expand Down Expand Up @@ -3893,6 +3900,11 @@ static void beiscsi_clean_port(struct beiscsi_hba *phba)
kfree(phba->ep_array);
}

/**
* beiscsi_cleanup_task()- Free driver resources of the task
* @task: ptr to the iscsi task
*
**/
static void beiscsi_cleanup_task(struct iscsi_task *task)
{
struct beiscsi_io_task *io_task = task->dd_data;
Expand Down Expand Up @@ -3940,6 +3952,13 @@ static void beiscsi_cleanup_task(struct iscsi_task *task)
spin_unlock(&phba->mgmt_sgl_lock);
io_task->psgl_handle = NULL;
}
if (io_task->mtask_addr) {
pci_unmap_single(phba->pcidev,
io_task->mtask_addr,
io_task->mtask_data_count,
PCI_DMA_TODEVICE);
io_task->mtask_addr = 0;
}
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions drivers/scsi/be2iscsi/be_main.h
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,8 @@ struct beiscsi_io_task {
struct be_cmd_bhs *cmd_bhs;
struct be_bus_address bhs_pa;
unsigned short bhs_len;
dma_addr_t mtask_addr;
uint32_t mtask_data_count;
};

struct be_nonio_bhs {
Expand Down

0 comments on commit d629c47

Please sign in to comment.