diff options
author | Kirill Artamonov <kartamonov@nvidia.com> | 2011-02-09 23:53:03 +0200 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2011-11-30 21:44:52 -0800 |
commit | 4e01c4c6f3399b59ae263b434c43e5c366cf1d35 (patch) | |
tree | e4c026ba581aae521fb525de980ff5ce770e8ef9 /drivers/video/tegra/nvmap/nvmap_dev.c | |
parent | cc519518d2cc078bf52dc0725d325332c7af862d (diff) |
nvmap: implementing K36 carveout compactor
bug 762482
Original-Change-Id: Ifadebc1b0c4eb0df89e179091acca0ff6e527e56
Reviewed-on: http://git-master/r/15743
Reviewed-by: Kirill Artamonov <kartamonov@nvidia.com>
Tested-by: Kirill Artamonov <kartamonov@nvidia.com>
Reviewed-by: Varun Colbert <vcolbert@nvidia.com>
Rebase-Id: R639e7f09f44c8919bd57a16a577b87db91160555
Diffstat (limited to 'drivers/video/tegra/nvmap/nvmap_dev.c')
-rw-r--r-- | drivers/video/tegra/nvmap/nvmap_dev.c | 38 |
1 files changed, 23 insertions, 15 deletions
diff --git a/drivers/video/tegra/nvmap/nvmap_dev.c b/drivers/video/tegra/nvmap/nvmap_dev.c index 2cea073499b7..3d0e69b83b51 100644 --- a/drivers/video/tegra/nvmap/nvmap_dev.c +++ b/drivers/video/tegra/nvmap/nvmap_dev.c @@ -402,9 +402,10 @@ out: } struct nvmap_heap_block *do_nvmap_carveout_alloc(struct nvmap_client *client, - size_t len, size_t align, - unsigned long usage, - unsigned int prot) + size_t len, size_t align, + unsigned long usage, + unsigned int prot, + struct nvmap_handle *handle) { struct nvmap_carveout_node *co_heap; struct nvmap_device *dev = client->dev; @@ -417,16 +418,17 @@ struct nvmap_heap_block *do_nvmap_carveout_alloc(struct nvmap_client *client, if (!(co_heap->heap_bit & usage)) continue; - block = nvmap_heap_alloc(co_heap->carveout, len, align, prot); + block = nvmap_heap_alloc(co_heap->carveout, len, + align, prot, handle); if (block) { /* flush any stale data that may be left in the * cache at the block's address, since the new * block may be mapped uncached */ if (nvmap_flush_heap_block(client, block, len)) { nvmap_heap_free(block); - return NULL; - } else - return block; + block = NULL; + } + return block; } } return NULL; @@ -441,7 +443,8 @@ static bool nvmap_carveout_freed(int count) struct nvmap_heap_block *nvmap_carveout_alloc(struct nvmap_client *client, size_t len, size_t align, unsigned long usage, - unsigned int prot) + unsigned int prot, + struct nvmap_handle *handle) { struct nvmap_heap_block *block; struct nvmap_carveout_node *co_heap; @@ -452,8 +455,8 @@ struct nvmap_heap_block *nvmap_carveout_alloc(struct nvmap_client *client, int count = 0; do { - block = do_nvmap_carveout_alloc(client, len, align, - usage, prot); + block = do_nvmap_carveout_alloc(client, len, align, usage, + prot, handle); if (!carveout_killer) return block; @@ -859,12 +862,17 @@ static void nvmap_vma_close(struct vm_area_struct *vma) { struct nvmap_vma_priv *priv = vma->vm_private_data; - if (priv && !atomic_dec_return(&priv->count)) { - if (priv->handle) - nvmap_handle_put(priv->handle); - kfree(priv); + if (priv) { + if (priv->handle) { + nvmap_usecount_dec(priv->handle); + BUG_ON(priv->handle->usecount < 0); + } + if (!atomic_dec_return(&priv->count)) { + if (priv->handle) + nvmap_handle_put(priv->handle); + kfree(priv); + } } - vma->vm_private_data = NULL; } |