diff options
author | Sri Krishna chowdary <schowdary@nvidia.com> | 2016-04-27 09:44:15 +0530 |
---|---|---|
committer | Matthew Pedro <mapedro@nvidia.com> | 2016-04-28 15:00:40 -0700 |
commit | fedeb7e91f994c868d79641b84fc1ffff3d1254a (patch) | |
tree | b2c4faf11b37270c961afa465a92990e707e4758 /drivers/video | |
parent | 084df2dcb7607c947d061056a66eef55f308512c (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/video')
-rw-r--r-- | drivers/video/tegra/nvmap/nvmap_dev.c | 17 | ||||
-rw-r--r-- | drivers/video/tegra/nvmap/nvmap_priv.h | 3 |
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 |