diff options
author | Roy Pledge <Roy.Pledge@freescale.com> | 2014-03-31 19:12:07 (GMT) |
---|---|---|
committer | Jose Rivera <German.Rivera@freescale.com> | 2014-04-01 16:21:17 (GMT) |
commit | 39367df58725d82e035e83105709c9441ddf8783 (patch) | |
tree | 9cbae45df9f76f3421028232f8dd7acc07f7d13e /drivers/staging/fsl_qbman | |
parent | 27ea4962a0c01dabcc30d719701386a66375d8c5 (diff) | |
download | linux-fsl-qoriq-39367df58725d82e035e83105709c9441ddf8783.tar.xz |
Reduce reference count of DMA memory fragments during unmap
If a process explictly unmapped DMA fragments the reference
count of each fragement wasn't properly decremented causing
a leak. This would only occur if the proccess explicitly
umapped the memory, exiting the process did correctly adjust
the reference counts
Signed-off-by: Roy Pledge <Roy.Pledge@freescale.com>
Change-Id: Ia9adfccd5249d17d5506796b1fe71c32f46cab30
Reviewed-on: http://git.am.freescale.net:8181/10527
Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
Reviewed-by: Geoff Thorpe <Geoff.Thorpe@freescale.com>
Reviewed-by: Jose Rivera <German.Rivera@freescale.com>
Diffstat (limited to 'drivers/staging/fsl_qbman')
-rw-r--r-- | drivers/staging/fsl_qbman/fsl_usdpaa.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/drivers/staging/fsl_qbman/fsl_usdpaa.c b/drivers/staging/fsl_qbman/fsl_usdpaa.c index 0e6adca..dbbc80f 100644 --- a/drivers/staging/fsl_qbman/fsl_usdpaa.c +++ b/drivers/staging/fsl_qbman/fsl_usdpaa.c @@ -1009,7 +1009,8 @@ static long ioctl_dma_unmap(struct ctx *ctx, void __user *arg) { struct mem_mapping *map; struct vm_area_struct *vma; - int ret; + int ret, i; + struct mem_fragment *current_frag; down_write(¤t->mm->mmap_sem); vma = find_vma(current->mm, (unsigned long)arg); @@ -1031,6 +1032,13 @@ static long ioctl_dma_unmap(struct ctx *ctx, void __user *arg) } map = NULL; map_match: + current_frag = map->root_frag; + for (i = 0; i < map->frag_count; i++) { + DPA_ASSERT(current_frag->refs > 0); + --current_frag->refs; + current_frag = list_entry(current_frag->list.prev, + struct mem_fragment, list); + } list_del(&map->list); compress_frags(); spin_unlock(&mem_lock); |