summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorSri Krishna chowdary <schowdary@nvidia.com>2016-04-27 09:44:15 +0530
committerMatthew Pedro <mapedro@nvidia.com>2016-04-28 15:00:40 -0700
commitfedeb7e91f994c868d79641b84fc1ffff3d1254a (patch)
treeb2c4faf11b37270c961afa465a92990e707e4758 /drivers
parent084df2dcb7607c947d061056a66eef55f308512c (diff)
video: tegra: nvmap: Add ref count in nvmap_vma_list
Add ref count to prevent invalid vma removal from the h->vmas list and also allow addition of a different vma which also has same nvmap_vma_priv as vm_private_data into the h->vmas list. Both cases are allowed in valid usage of nvmap_vma_open/nvmap_vma_close. Bug 200164002 Change-Id: Ifc4d281dd91e1d072a9a3ee85e925040bd65a6bc Signed-off-by: Sri Krishna chowdary <schowdary@nvidia.com> Signed-off-by: Bryan Wu <pengw@nvidia.com> Reviewed-on: http://git-master/r/1133708 Reviewed-by: Krishna Reddy <vdumpa@nvidia.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/video/tegra/nvmap/nvmap_dev.c17
-rw-r--r--drivers/video/tegra/nvmap/nvmap_priv.h3
2 files changed, 15 insertions, 5 deletions
diff --git a/drivers/video/tegra/nvmap/nvmap_dev.c b/drivers/video/tegra/nvmap/nvmap_dev.c
index d90fc4a417ba..d1de4dce9336 100644
--- a/drivers/video/tegra/nvmap/nvmap_dev.c
+++ b/drivers/video/tegra/nvmap/nvmap_dev.c
@@ -3,7 +3,7 @@
*
* User-space interface to nvmap
*
- * Copyright (c) 2011-2014, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2011-2016, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -645,7 +645,12 @@ void nvmap_vma_open(struct vm_area_struct *vma)
* handle offsets
*/
list_for_each_entry(tmp, &h->vmas, list) {
- BUG_ON(tmp->vma == vma);
+ /* if vma exits in list, just increment refcount */
+ if (tmp->vma == vma) {
+ atomic_inc(&tmp->ref);
+ kfree(vma_list);
+ goto unlock;
+ }
if (!vma_pos_found && (current_pid == tmp->pid)) {
if (vma->vm_pgoff < tmp->vma->vm_pgoff) {
@@ -659,7 +664,9 @@ void nvmap_vma_open(struct vm_area_struct *vma)
vma_list->vma = vma;
vma_list->pid = current_pid;
+ atomic_set(&vma_list->ref, 1);
list_add_tail(&vma_list->list, tmp_head);
+unlock:
mutex_unlock(&h->lock);
} else {
WARN(1, "vma not tracked");
@@ -683,8 +690,10 @@ static void nvmap_vma_close(struct vm_area_struct *vma)
list_for_each_entry(vma_list, &h->vmas, list) {
if (vma_list->vma != vma)
continue;
- list_del(&vma_list->list);
- kfree(vma_list);
+ if (atomic_dec_return(&vma_list->ref) == 0) {
+ list_del(&vma_list->list);
+ kfree(vma_list);
+ }
vma_found = true;
break;
}
diff --git a/drivers/video/tegra/nvmap/nvmap_priv.h b/drivers/video/tegra/nvmap/nvmap_priv.h
index 977897a61aa2..a90a3269cd62 100644
--- a/drivers/video/tegra/nvmap/nvmap_priv.h
+++ b/drivers/video/tegra/nvmap/nvmap_priv.h
@@ -3,7 +3,7 @@
*
* GPU memory management driver for Tegra
*
- * Copyright (c) 2009-2014, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2009-2016, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -91,6 +91,7 @@ struct nvmap_vma_list {
struct list_head list;
struct vm_area_struct *vma;
pid_t pid;
+ atomic_t ref;
};
/* handles allocated using shared system memory (either IOVMM- or high-order