2 * Copyright (C) 2013-2015 ARM Limited. All rights reserved.
4 * This program is free software and is provided to you under the terms of the GNU General Public License version 2
5 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
7 * A copy of the licence is included with the program, and can also be obtained from Free Software
8 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
11 #include <linux/list.h>
\r
12 #include <linux/mm.h>
\r
13 #include <linux/mm_types.h>
\r
14 #include <linux/fs.h>
\r
15 #include <linux/dma-mapping.h>
\r
16 #include <linux/slab.h>
\r
17 #include <linux/platform_device.h>
\r
19 #include "mali_osk.h"
\r
20 #include "mali_osk_mali.h"
\r
21 #include "mali_kernel_linux.h"
\r
22 #include "mali_scheduler.h"
\r
23 #include "mali_memory_os_alloc.h"
\r
24 #include "mali_memory_manager.h"
\r
25 #include "mali_memory_virtual.h"
\r
29 *internal helper to link node into the rb-tree
\r
31 static inline void _mali_vma_offset_add_rb(struct mali_allocation_manager *mgr,
\r
32 struct mali_vma_node *node)
\r
34 struct rb_node **iter = &mgr->allocation_mgr_rb.rb_node;
\r
35 struct rb_node *parent = NULL;
\r
36 struct mali_vma_node *iter_node;
\r
38 while (likely(*iter)) {
\r
40 iter_node = rb_entry(*iter, struct mali_vma_node, vm_rb);
\r
42 if (node->vm_node.start < iter_node->vm_node.start)
\r
43 iter = &(*iter)->rb_left;
\r
44 else if (node->vm_node.start > iter_node->vm_node.start)
\r
45 iter = &(*iter)->rb_right;
\r
47 MALI_DEBUG_ASSERT(0);
\r
50 rb_link_node(&node->vm_rb, parent, iter);
\r
51 rb_insert_color(&node->vm_rb, &mgr->allocation_mgr_rb);
\r
55 * mali_vma_offset_add() - Add offset node to RB Tree
\r
57 int mali_vma_offset_add(struct mali_allocation_manager *mgr,
\r
58 struct mali_vma_node *node)
\r
61 write_lock(&mgr->vm_lock);
\r
63 if (node->vm_node.allocated) {
\r
67 _mali_vma_offset_add_rb(mgr, node);
\r
68 /* set to allocated */
\r
69 node->vm_node.allocated = 1;
\r
72 write_unlock(&mgr->vm_lock);
\r
77 * mali_vma_offset_remove() - Remove offset node from RB tree
\r
79 void mali_vma_offset_remove(struct mali_allocation_manager *mgr,
\r
80 struct mali_vma_node *node)
\r
82 write_lock(&mgr->vm_lock);
\r
84 if (node->vm_node.allocated) {
\r
85 rb_erase(&node->vm_rb, &mgr->allocation_mgr_rb);
\r
86 memset(&node->vm_node, 0, sizeof(node->vm_node));
\r
88 write_unlock(&mgr->vm_lock);
\r
92 * mali_vma_offset_search - Search the node in RB tree
\r
94 struct mali_vma_node *mali_vma_offset_search(struct mali_allocation_manager *mgr,
\r
95 unsigned long start, unsigned long pages)
\r
97 struct mali_vma_node *node, *best;
\r
98 struct rb_node *iter;
\r
99 unsigned long offset;
\r
100 read_lock(&mgr->vm_lock);
\r
102 iter = mgr->allocation_mgr_rb.rb_node;
\r
105 while (likely(iter)) {
\r
106 node = rb_entry(iter, struct mali_vma_node, vm_rb);
\r
107 offset = node->vm_node.start;
\r
108 if (start >= offset) {
\r
109 iter = iter->rb_right;
\r
111 if (start == offset)
\r
114 iter = iter->rb_left;
\r
119 offset = best->vm_node.start + best->vm_node.size;
\r
120 if (offset <= start + pages)
\r
123 read_unlock(&mgr->vm_lock);
\r