]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/commitdiff
video: tegra: nvmap: Add ref count in nvmap_vma_list
authorSri Krishna chowdary <schowdary@nvidia.com>
Wed, 27 Apr 2016 04:14:15 +0000 (09:44 +0530)
committerMatthew Pedro <mapedro@nvidia.com>
Thu, 28 Apr 2016 22:00:40 +0000 (15:00 -0700)
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>
drivers/video/tegra/nvmap/nvmap_dev.c
drivers/video/tegra/nvmap/nvmap_priv.h

index d90fc4a417baf7d519ad5d1746e897726185a092..d1de4dce933611d78d00b58e0262c7a480f34f1a 100644 (file)
@@ -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;
        }
index 977897a61aa23a429ccc2429927c9dbba8e6f77d..a90a3269cd62cce2e713f0c23dd0efd8f4443796 100644 (file)
@@ -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