]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/commitdiff
gpu: nvgpu: Change va_node free behavior
authorAlex Waterman <alexw@nvidia.com>
Thu, 22 Jan 2015 20:48:10 +0000 (12:48 -0800)
committerTerje Bergstrom <tbergstrom@nvidia.com>
Tue, 27 Jan 2015 22:52:14 +0000 (14:52 -0800)
Decrement the ref count on all mapped_buffers belonging to a va_node
when a va_node is freed. This prevents userspace from leaking some
mapped_buffers in some cases.

This does prevent userspace from keeping a buffer around after freeing
a space allocation if the buffer in question is not otherwise ref
counted. Not sure if this is a bad thing for userspace or not.

Bug 1600686

Change-Id: I659ccbda5935d44086fd367bd2110f7d0f066194
Signed-off-by: Alex Waterman <alexw@nvidia.com>
Reviewed-on: http://git-master/r/676629
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Tested-by: Terje Bergstrom <tbergstrom@nvidia.com>
drivers/gpu/nvgpu/gk20a/mm_gk20a.c

index f53e14dfe6b8be11dd38d60a1d5bab4e817b6277..c7b651dbe7cf4c8b49709056dcebe63ac9f19bbb 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * GK20A memory management
  *
- * Copyright (c) 2011-2014, NVIDIA CORPORATION.  All rights reserved.
+ * Copyright (c) 2011-2015, NVIDIA CORPORATION.  All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -2474,12 +2474,13 @@ int gk20a_vm_free_space(struct gk20a_as_share *as_share,
        if (va_node) {
                struct mapped_buffer_node *buffer, *n;
 
-               /* there is no need to unallocate the buffers in va. Just
-                * convert them into normal buffers */
-
+               /* Decrement the ref count on all buffers in this va_node. This
+                * allows userspace to let the kernel free mappings that are
+                * only used by this va_node. */
                list_for_each_entry_safe(buffer, n,
                        &va_node->va_buffers_list, va_buffers_list) {
                        list_del_init(&buffer->va_buffers_list);
+                       kref_put(&buffer->ref, gk20a_vm_unmap_locked_kref);
                }
 
                list_del(&va_node->reserved_va_list);