summaryrefslogtreecommitdiff
path: root/drivers/video/tegra/nvmap/nvmap_handle.c
diff options
context:
space:
mode:
authorKirill Artamonov <kartamonov@nvidia.com>2011-02-18 14:58:41 +0200
committerDan Willemsen <dwillemsen@nvidia.com>2011-11-30 21:44:53 -0800
commite213542a2f06930c44ddc41ddcbc2035436a3973 (patch)
tree26640cdad04168e5a35df519e19295df23556b70 /drivers/video/tegra/nvmap/nvmap_handle.c
parent6083867a56f3b4f535fdd49366eae848a6537446 (diff)
video: tegra: nvmap: fix potential deadlock
Enabled mutex debugging reavealed potential deadlocks introduced with compaction. Handle spin lock replaced with mutex. Heap functions cannot be protected with spinlock because they call kernel slab allocation functions which cannot be called from atomic context. nvmap_client ref_lock is also replaced with mutex. Otherwise we cannot access heap parameters protected by mutex nvmap_handle lock. Extra locking for handle->owner removed. bug 793364 Original-Change-Id: I635ce9ebf259dd7bf8802457567f93b7be5795ea Reviewed-on: http://git-master/r/19850 Reviewed-by: Kirill Artamonov <kartamonov@nvidia.com> Tested-by: Kirill Artamonov <kartamonov@nvidia.com> Reviewed-by: Daniel Willemsen <dwillemsen@nvidia.com> Rebase-Id: Reaa132703e278d75371d5e2b25426794aa8e0e4e
Diffstat (limited to 'drivers/video/tegra/nvmap/nvmap_handle.c')
-rw-r--r--drivers/video/tegra/nvmap/nvmap_handle.c12
1 files changed, 5 insertions, 7 deletions
diff --git a/drivers/video/tegra/nvmap/nvmap_handle.c b/drivers/video/tegra/nvmap/nvmap_handle.c
index c8a2c1fc9c79..dc3be30ca2f5 100644
--- a/drivers/video/tegra/nvmap/nvmap_handle.c
+++ b/drivers/video/tegra/nvmap/nvmap_handle.c
@@ -371,11 +371,11 @@ void nvmap_free_handle_id(struct nvmap_client *client, unsigned long id)
atomic_sub(h->size, &client->iovm_commit);
if (h->alloc && !h->heap_pgalloc) {
- spin_lock(&h->lock);
+ mutex_lock(&h->lock);
nvmap_carveout_commit_subtract(client,
nvmap_heap_to_arg(nvmap_block_to_heap(h->carveout)),
h->size);
- spin_unlock(&h->lock);
+ mutex_unlock(&h->lock);
}
nvmap_ref_unlock(client);
@@ -387,10 +387,8 @@ void nvmap_free_handle_id(struct nvmap_client *client, unsigned long id)
while (pins--)
nvmap_unpin_handles(client, &ref->handle, 1);
- spin_lock(&h->lock);
if (h->owner == client)
h->owner = NULL;
- spin_unlock(&h->lock);
kfree(ref);
@@ -446,7 +444,7 @@ struct nvmap_handle_ref *nvmap_create_handle(struct nvmap_client *client,
BUG_ON(!h->owner);
h->size = h->orig_size = size;
h->flags = NVMAP_HANDLE_WRITE_COMBINE;
- spin_lock_init(&h->lock);
+ mutex_init(&h->lock);
nvmap_handle_add(client->dev, h);
@@ -516,11 +514,11 @@ struct nvmap_handle_ref *nvmap_duplicate_handle_id(struct nvmap_client *client,
}
if (!h->heap_pgalloc) {
- spin_lock(&h->lock);
+ mutex_lock(&h->lock);
nvmap_carveout_commit_add(client,
nvmap_heap_to_arg(nvmap_block_to_heap(h->carveout)),
h->size);
- spin_unlock(&h->lock);
+ mutex_unlock(&h->lock);
}
atomic_set(&ref->dupes, 1);