diff options
author | Krishna Reddy <vdumpa@nvidia.com> | 2013-01-16 11:24:38 -0800 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2013-09-14 01:29:20 -0700 |
commit | b49f0e7426c32c85d351b78400f41da3eec3beda (patch) | |
tree | b0a7ca0e1f909c34a2c9fcd7678e0f3dd849c4db /drivers/video | |
parent | 91580eef80e9f0aee2cd74cc9cedf921ddcfb98d (diff) |
video: tegra: nvmap: protect usecount variable from race conditions
make usecount variable atomic to avoid race conditions in
nvmap_usecount_dec().
optimize away usecount variable when carveout compaction is disabled.
Bug 1215506
Change-Id: I570bcc258e578ace2b1e8151c027fcd4cf559bda
Signed-off-by: Krishna Reddy <vdumpa@nvidia.com>
Reviewed-on: http://git-master/r/191753
Reviewed-by: Jon Mayo <jmayo@nvidia.com>
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Kirill Artamonov <kartamonov@nvidia.com>
Diffstat (limited to 'drivers/video')
-rw-r--r-- | drivers/video/tegra/nvmap/nvmap.h | 6 | ||||
-rw-r--r-- | drivers/video/tegra/nvmap/nvmap_dev.c | 8 | ||||
-rw-r--r-- | drivers/video/tegra/nvmap/nvmap_heap.c | 17 |
3 files changed, 18 insertions, 13 deletions
diff --git a/drivers/video/tegra/nvmap/nvmap.h b/drivers/video/tegra/nvmap/nvmap.h index 606ae330ca44..c78de1f0b6ae 100644 --- a/drivers/video/tegra/nvmap/nvmap.h +++ b/drivers/video/tegra/nvmap/nvmap.h @@ -85,7 +85,11 @@ struct nvmap_handle { struct rb_node node; /* entry on global handle tree */ atomic_t ref; /* reference count (i.e., # of duplications) */ atomic_t pin; /* pin count */ - unsigned int usecount; /* how often is used */ +#ifdef CONFIG_NVMAP_CARVEOUT_COMPACTOR + atomic_t usecount; /* holds map count on carveout handle and is + used to avoid relocation during + carveout compaction */ +#endif unsigned long flags; size_t size; /* padded (as-allocated) size */ size_t orig_size; /* original (as-requested) size */ diff --git a/drivers/video/tegra/nvmap/nvmap_dev.c b/drivers/video/tegra/nvmap/nvmap_dev.c index 456d8a91e0db..4846ce0aa373 100644 --- a/drivers/video/tegra/nvmap/nvmap_dev.c +++ b/drivers/video/tegra/nvmap/nvmap_dev.c @@ -931,8 +931,7 @@ static void nvmap_vma_open(struct vm_area_struct *vma) BUG_ON(!priv); atomic_inc(&priv->count); - if(priv->handle) - nvmap_usecount_inc(priv->handle); + nvmap_usecount_inc(priv->handle); } static void nvmap_vma_close(struct vm_area_struct *vma) @@ -940,10 +939,7 @@ static void nvmap_vma_close(struct vm_area_struct *vma) struct nvmap_vma_priv *priv = vma->vm_private_data; if (priv) { - if (priv->handle) { - BUG_ON(priv->handle->usecount == 0); - nvmap_usecount_dec(priv->handle); - } + nvmap_usecount_dec(priv->handle); if (!atomic_dec_return(&priv->count)) { if (priv->handle) nvmap_handle_put(priv->handle); diff --git a/drivers/video/tegra/nvmap/nvmap_heap.c b/drivers/video/tegra/nvmap/nvmap_heap.c index 75fa9704f6bd..2b37ee3f9098 100644 --- a/drivers/video/tegra/nvmap/nvmap_heap.c +++ b/drivers/video/tegra/nvmap/nvmap_heap.c @@ -721,7 +721,7 @@ static struct nvmap_heap_block *do_heap_relocate_listblock( if (atomic_read(&handle->pin)) goto fail; /* abort if block is mapped */ - if (handle->usecount) + if (atomic_read(&handle->usecount)) goto fail; if (fast) { @@ -842,19 +842,24 @@ static void nvmap_heap_compact(struct nvmap_heap *heap, void nvmap_usecount_inc(struct nvmap_handle *h) { - if (h->alloc && !h->heap_pgalloc) { +#ifdef CONFIG_NVMAP_CARVEOUT_COMPACTOR + if (h && !h->heap_pgalloc) { mutex_lock(&h->lock); - h->usecount++; + atomic_inc(&h->usecount); mutex_unlock(&h->lock); - } else { - h->usecount++; } +#endif } void nvmap_usecount_dec(struct nvmap_handle *h) { - h->usecount--; +#ifdef CONFIG_NVMAP_CARVEOUT_COMPACTOR + if (h && !h->heap_pgalloc) { + BUG_ON(atomic_read(&h->usecount) == 0); + atomic_dec(&h->usecount); + } +#endif } /* nvmap_heap_alloc: allocates a block of memory of len bytes, aligned to |