vide: tegra: host: fix nvmap handle leak
Krishna Reddy [Mon, 9 Sep 2013 23:28:16 +0000 (16:28 -0700)]
nvmap pinned handle in pinned during nvhost_nvmap_pin. But it
is not unpinned during nvhost_nvmap_unpin. This holds the handle
forever and leaks the memory.
Bug 1356091

Change-Id: Ie2d884720f21527c24ea79de6f128a9b29303fdd
Signed-off-by: Krishna Reddy <vdumpa@nvidia.com>
Reviewed-on: http://git-master/r/272190
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>

drivers/video/tegra/host/nvmap.c

index b482775..555f6b5 100644 (file)
@@ -39,6 +39,7 @@ struct nvhost_nvmap_as_data {
        size_t len;
        struct sg_table *sgt;
        int pin_count;
+       int nvmap_pin_count;
        int flags;
 };
 
@@ -209,6 +210,7 @@ struct sg_table *nvhost_nvmap_pin(struct mem_mgr *mgr,
                }
 
                sg_dma_address(sgt->sgl) = addr;
+               as_priv->nvmap_pin_count++;
        } else if (as_priv->pin_count == 0 &&
                   sg_dma_address(sgt->sgl) == 0) {
                int ents;
@@ -243,6 +245,14 @@ void nvhost_nvmap_unpin(struct mem_mgr *mgr, struct mem_handle *handle,
        mutex_lock(&priv->lock);
        as = priv->as[tegra_smmu_get_asid(dev)];
        if (as) {
+               if (as->flags & BIT(FLAG_CARVEOUT))
+                       ;
+               else if (as->flags & BIT(FLAG_NVMAP_MAPPED) &&
+                        as->nvmap_pin_count) {
+                       as->nvmap_pin_count--;
+                       sg_dma_address(as->sgt->sgl) = 0;
+                       nvmap_unpin(as->client, as->ref);
+               }
                as->pin_count--;
                WARN_ON(as->pin_count < 0);
        }