diff options
author | John Soni Jose <sony.john-n@emulex.com> | 2012-10-19 19:12:00 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2012-11-26 23:59:35 -0500 |
commit | d629c47171ccc281bbb02507f9521a6125782e9b (patch) | |
tree | a44162a31596ad10452f1a47d43d7e16333ce5ae | |
parent | 6763daae8fcf4d7581238385aa326f3dbe8f16c5 (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.c | 39 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_main.h | 2 |
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 | **/ | ||
2245 | static void hwi_write_buffer(struct iscsi_wrb *pwrb, struct iscsi_task *task) | 2250 | static 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 | **/ | ||
3896 | static void beiscsi_cleanup_task(struct iscsi_task *task) | 3908 | static 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 | ||
415 | struct be_nonio_bhs { | 417 | struct be_nonio_bhs { |