From 5789e7dcba12b39bf20eb14c92387e9026a35672 Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Wed, 15 Feb 2012 15:02:14 +0200 Subject: [PATCH] gfx: drv: fix resource leak in psb_gtt_map_meminfo If psb_gtt_map_meminfo was called with an already mapped handle a node would be allocated with drm_mm_get_block_atomic in psb_gtt_mm_alloc_mem. Later, on psb_gtt_mm_alloc_insert_mem_mapping (called by psb_gtt_add_node), the reference to the allocated node would be replaced by the node previously allocated for the handle, so the former was never free'd. This commit changes psb_gtt_map_meminfo to check for an existing node before allocating a new one. Signed-off-by: Ander Conselvan de Oliveira Reviewed-by: Imre Deak Signed-off-by: Kirill A. Shutemov --- drivers/staging/mrst/drv/psb_gtt.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/drivers/staging/mrst/drv/psb_gtt.c b/drivers/staging/mrst/drv/psb_gtt.c index 81ca19c..b4dfd19 100644 --- a/drivers/staging/mrst/drv/psb_gtt.c +++ b/drivers/staging/mrst/drv/psb_gtt.c @@ -772,6 +772,27 @@ static void psb_gtt_mm_free_mem(struct psb_gtt_mm *mm, struct drm_mm_node *node) spin_unlock(&mm->lock); } +static struct psb_gtt_mem_mapping * +psb_gtt_find_mapping_for_key(struct psb_gtt_mm *mm, u32 tgid, u32 key) +{ + struct psb_gtt_hash_entry *hentry; + struct psb_gtt_mem_mapping *mapping; + + spin_lock(&mm->lock); + + hentry = psb_gtt_mm_get_ht_by_pid_locked(mm, tgid); + if (IS_ERR(hentry)) { + spin_unlock(&mm->lock); + return ERR_CAST(hentry); + } + + mapping = psb_gtt_mm_get_mem_mapping_locked(&hentry->ht, key); + + spin_unlock(&mm->lock); + + return mapping; +} + int psb_gtt_map_meminfo(struct drm_device *dev, IMG_HANDLE hKernelMemInfo, uint32_t *offset) @@ -818,6 +839,14 @@ int psb_gtt_map_meminfo(struct drm_device *dev, DRM_DEBUG("get %u pages\n", pages); + /* check if memory is already mapped */ + mapping = psb_gtt_find_mapping_for_key(mm, psb_get_tgid(), + (u32) hKernelMemInfo); + if (!IS_ERR(mapping)) { + *offset = mapping->node->start; + return 0; + } + /* alloc memory in TT apeture */ node = psb_gtt_mm_alloc_mem(mm, pages, 0); if (IS_ERR(node)) { -- 2.7.4