aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Soni Jose <sony.john-n@emulex.com>2012-10-19 19:12:00 -0400
committerJames Bottomley <JBottomley@Parallels.com>2012-11-26 23:59:35 -0500
commitd629c47171ccc281bbb02507f9521a6125782e9b (patch)
treea44162a31596ad10452f1a47d43d7e16333ce5ae
parent6763daae8fcf4d7581238385aa326f3dbe8f16c5 (diff)
[SCSI] be2iscsi: Fix memory leak in control path of driver
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>
-rw-r--r--drivers/scsi/be2iscsi/be_main.c39
-rw-r--r--drivers/scsi/be2iscsi/be_main.h2
2 files changed, 31 insertions, 10 deletions
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index b52c5c0a4fd0..db3ea1496e96 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -2242,10 +2242,14 @@ hwi_write_sgl(struct iscsi_wrb *pwrb, struct scatterlist *sg,
2242 AMAP_SET_BITS(struct amap_iscsi_sge, last_sge, psgl, 1); 2242 AMAP_SET_BITS(struct amap_iscsi_sge, last_sge, psgl, 1);
2243} 2243}
2244 2244
2245/**
2246 * hwi_write_buffer()- Populate the WRB with task info
2247 * @pwrb: ptr to the WRB entry
2248 * @task: iscsi task which is to be executed
2249 **/
2245static void hwi_write_buffer(struct iscsi_wrb *pwrb, struct iscsi_task *task) 2250static void hwi_write_buffer(struct iscsi_wrb *pwrb, struct iscsi_task *task)
2246{ 2251{
2247 struct iscsi_sge *psgl; 2252 struct iscsi_sge *psgl;
2248 unsigned long long addr;
2249 struct beiscsi_io_task *io_task = task->dd_data; 2253 struct beiscsi_io_task *io_task = task->dd_data;
2250 struct beiscsi_conn *beiscsi_conn = io_task->conn; 2254 struct beiscsi_conn *beiscsi_conn = io_task->conn;
2251 struct beiscsi_hba *phba = beiscsi_conn->phba; 2255 struct beiscsi_hba *phba = beiscsi_conn->phba;
@@ -2259,24 +2263,27 @@ static void hwi_write_buffer(struct iscsi_wrb *pwrb, struct iscsi_task *task)
2259 if (task->data) { 2263 if (task->data) {
2260 if (task->data_count) { 2264 if (task->data_count) {
2261 AMAP_SET_BITS(struct amap_iscsi_wrb, dsp, pwrb, 1); 2265 AMAP_SET_BITS(struct amap_iscsi_wrb, dsp, pwrb, 1);
2262 addr = (u64) pci_map_single(phba->pcidev, 2266 io_task->mtask_addr = pci_map_single(phba->pcidev,
2263 task->data, 2267 task->data,
2264 task->data_count, 1); 2268 task->data_count,
2269 PCI_DMA_TODEVICE);
2270
2271 io_task->mtask_data_count = task->data_count;
2265 } else { 2272 } else {
2266 AMAP_SET_BITS(struct amap_iscsi_wrb, dsp, pwrb, 0); 2273 AMAP_SET_BITS(struct amap_iscsi_wrb, dsp, pwrb, 0);
2267 addr = 0; 2274 io_task->mtask_addr = 0;
2268 } 2275 }
2269 AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_addr_lo, pwrb, 2276 AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_addr_lo, pwrb,
2270 ((u32)(addr & 0xFFFFFFFF))); 2277 lower_32_bits(io_task->mtask_addr));
2271 AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_addr_hi, pwrb, 2278 AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_addr_hi, pwrb,
2272 ((u32)(addr >> 32))); 2279 upper_32_bits(io_task->mtask_addr));
2273 AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_len, pwrb, 2280 AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_len, pwrb,
2274 task->data_count); 2281 task->data_count);
2275 2282
2276 AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_last, pwrb, 1); 2283 AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_last, pwrb, 1);
2277 } else { 2284 } else {
2278 AMAP_SET_BITS(struct amap_iscsi_wrb, dsp, pwrb, 0); 2285 AMAP_SET_BITS(struct amap_iscsi_wrb, dsp, pwrb, 0);
2279 addr = 0; 2286 io_task->mtask_addr = 0;
2280 } 2287 }
2281 2288
2282 psgl = (struct iscsi_sge *)io_task->psgl_handle->pfrag; 2289 psgl = (struct iscsi_sge *)io_task->psgl_handle->pfrag;
@@ -2299,9 +2306,9 @@ static void hwi_write_buffer(struct iscsi_wrb *pwrb, struct iscsi_task *task)
2299 psgl++; 2306 psgl++;
2300 if (task->data) { 2307 if (task->data) {
2301 AMAP_SET_BITS(struct amap_iscsi_sge, addr_lo, psgl, 2308 AMAP_SET_BITS(struct amap_iscsi_sge, addr_lo, psgl,
2302 ((u32)(addr & 0xFFFFFFFF))); 2309 lower_32_bits(io_task->mtask_addr));
2303 AMAP_SET_BITS(struct amap_iscsi_sge, addr_hi, psgl, 2310 AMAP_SET_BITS(struct amap_iscsi_sge, addr_hi, psgl,
2304 ((u32)(addr >> 32))); 2311 upper_32_bits(io_task->mtask_addr));
2305 } 2312 }
2306 AMAP_SET_BITS(struct amap_iscsi_sge, len, psgl, 0x106); 2313 AMAP_SET_BITS(struct amap_iscsi_sge, len, psgl, 0x106);
2307 } 2314 }
@@ -3893,6 +3900,11 @@ static void beiscsi_clean_port(struct beiscsi_hba *phba)
3893 kfree(phba->ep_array); 3900 kfree(phba->ep_array);
3894} 3901}
3895 3902
3903/**
3904 * beiscsi_cleanup_task()- Free driver resources of the task
3905 * @task: ptr to the iscsi task
3906 *
3907 **/
3896static void beiscsi_cleanup_task(struct iscsi_task *task) 3908static void beiscsi_cleanup_task(struct iscsi_task *task)
3897{ 3909{
3898 struct beiscsi_io_task *io_task = task->dd_data; 3910 struct beiscsi_io_task *io_task = task->dd_data;
@@ -3940,6 +3952,13 @@ static void beiscsi_cleanup_task(struct iscsi_task *task)
3940 spin_unlock(&phba->mgmt_sgl_lock); 3952 spin_unlock(&phba->mgmt_sgl_lock);
3941 io_task->psgl_handle = NULL; 3953 io_task->psgl_handle = NULL;
3942 } 3954 }
3955 if (io_task->mtask_addr) {
3956 pci_unmap_single(phba->pcidev,
3957 io_task->mtask_addr,
3958 io_task->mtask_data_count,
3959 PCI_DMA_TODEVICE);
3960 io_task->mtask_addr = 0;
3961 }
3943 } 3962 }
3944 } 3963 }
3945} 3964}
diff --git a/drivers/scsi/be2iscsi/be_main.h b/drivers/scsi/be2iscsi/be_main.h
index b8912263ef4e..f4e8d19c3828 100644
--- a/drivers/scsi/be2iscsi/be_main.h
+++ b/drivers/scsi/be2iscsi/be_main.h
@@ -410,6 +410,8 @@ struct beiscsi_io_task {
410 struct be_cmd_bhs *cmd_bhs; 410 struct be_cmd_bhs *cmd_bhs;
411 struct be_bus_address bhs_pa; 411 struct be_bus_address bhs_pa;
412 unsigned short bhs_len; 412 unsigned short bhs_len;
413 dma_addr_t mtask_addr;
414 uint32_t mtask_data_count;
413}; 415};
414 416
415struct be_nonio_bhs { 417struct be_nonio_bhs {