summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/common/mm/buddy_allocator_priv.h
diff options
context:
space:
mode:
authorAlex Waterman <alexw@nvidia.com>2016-12-20 16:55:48 -0500
committermobile promotions <svcmobile_promotions@nvidia.com>2017-01-09 15:33:16 -0500
commit6df3992b60959d32c7113cb77e131a2547174f3a (patch)
treeefbdc9e6ccd2330d5c469ca0783ecb0137da8fc4 /drivers/gpu/nvgpu/common/mm/buddy_allocator_priv.h
parente229514bece5a109cdbfe263f6329efe987e5939 (diff)
gpu: nvgpu: Move allocators to common/mm/
Move the GPU allocators to common/mm/ since the allocators are common code across all GPUs. Also rename the allocator code to move away from gk20a_ prefixed structs and functions. This caused one issue with the nvgpu_alloc() and nvgpu_free() functions. There was a function for allocating either with kmalloc() or vmalloc() depending on the size of the allocation. Those have now been renamed to nvgpu_kalloc() and nvgpu_kfree(). Bug 1799159 Change-Id: Iddda92c013612bcb209847084ec85b8953002fa5 Signed-off-by: Alex Waterman <alexw@nvidia.com> Reviewed-on: http://git-master/r/1274400 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/common/mm/buddy_allocator_priv.h')
-rw-r--r--drivers/gpu/nvgpu/common/mm/buddy_allocator_priv.h192
1 files changed, 192 insertions, 0 deletions
diff --git a/drivers/gpu/nvgpu/common/mm/buddy_allocator_priv.h b/drivers/gpu/nvgpu/common/mm/buddy_allocator_priv.h
new file mode 100644
index 00000000..50a11f14
--- /dev/null
+++ b/drivers/gpu/nvgpu/common/mm/buddy_allocator_priv.h
@@ -0,0 +1,192 @@
1/*
2 * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#ifndef BUDDY_ALLOCATOR_PRIV_H
18#define BUDDY_ALLOCATOR_PRIV_H
19
20#include <linux/list.h>
21#include <linux/rbtree.h>
22
23struct nvgpu_allocator;
24struct vm_gk20a;
25
26/*
27 * Each buddy is an element in a binary tree.
28 */
29struct nvgpu_buddy {
30 struct nvgpu_buddy *parent; /* Parent node. */
31 struct nvgpu_buddy *buddy; /* This node's buddy. */
32 struct nvgpu_buddy *left; /* Lower address sub-node. */
33 struct nvgpu_buddy *right; /* Higher address sub-node. */
34
35 struct list_head buddy_entry; /* List entry for various lists. */
36 struct rb_node alloced_entry; /* RB tree of allocations. */
37
38 u64 start; /* Start address of this buddy. */
39 u64 end; /* End address of this buddy. */
40 u64 order; /* Buddy order. */
41
42#define BALLOC_BUDDY_ALLOCED 0x1
43#define BALLOC_BUDDY_SPLIT 0x2
44#define BALLOC_BUDDY_IN_LIST 0x4
45 int flags; /* List of associated flags. */
46
47 /*
48 * Size of the PDE this buddy is using. This allows for grouping like
49 * sized allocations into the same PDE. This uses the gmmu_pgsz_gk20a
50 * enum except for the BALLOC_PTE_SIZE_ANY specifier.
51 */
52#define BALLOC_PTE_SIZE_ANY -1
53 int pte_size;
54};
55
56#define __buddy_flag_ops(flag, flag_up) \
57 static inline int buddy_is_ ## flag(struct nvgpu_buddy *b) \
58 { \
59 return b->flags & BALLOC_BUDDY_ ## flag_up; \
60 } \
61 static inline void buddy_set_ ## flag(struct nvgpu_buddy *b) \
62 { \
63 b->flags |= BALLOC_BUDDY_ ## flag_up; \
64 } \
65 static inline void buddy_clr_ ## flag(struct nvgpu_buddy *b) \
66 { \
67 b->flags &= ~BALLOC_BUDDY_ ## flag_up; \
68 }
69
70/*
71 * int buddy_is_alloced(struct nvgpu_buddy *b);
72 * void buddy_set_alloced(struct nvgpu_buddy *b);
73 * void buddy_clr_alloced(struct nvgpu_buddy *b);
74 *
75 * int buddy_is_split(struct nvgpu_buddy *b);
76 * void buddy_set_split(struct nvgpu_buddy *b);
77 * void buddy_clr_split(struct nvgpu_buddy *b);
78 *
79 * int buddy_is_in_list(struct nvgpu_buddy *b);
80 * void buddy_set_in_list(struct nvgpu_buddy *b);
81 * void buddy_clr_in_list(struct nvgpu_buddy *b);
82 */
83__buddy_flag_ops(alloced, ALLOCED);
84__buddy_flag_ops(split, SPLIT);
85__buddy_flag_ops(in_list, IN_LIST);
86
87/*
88 * Keeps info for a fixed allocation.
89 */
90struct nvgpu_fixed_alloc {
91 struct list_head buddies; /* List of buddies. */
92 struct rb_node alloced_entry; /* RB tree of fixed allocations. */
93
94 u64 start; /* Start of fixed block. */
95 u64 end; /* End address. */
96};
97
98/*
99 * GPU buddy allocator for the various GPU address spaces. Each addressable unit
100 * doesn't have to correspond to a byte. In some cases each unit is a more
101 * complex object such as a comp_tag line or the like.
102 *
103 * The max order is computed based on the size of the minimum order and the size
104 * of the address space.
105 *
106 * order_size is the size of an order 0 buddy.
107 */
108struct nvgpu_buddy_allocator {
109 struct nvgpu_allocator *owner; /* Owner of this buddy allocator. */
110 struct vm_gk20a *vm; /* Parent VM - can be NULL. */
111
112 u64 base; /* Base address of the space. */
113 u64 length; /* Length of the space. */
114 u64 blk_size; /* Size of order 0 allocation. */
115 u64 blk_shift; /* Shift to divide by blk_size. */
116
117 /* Internal stuff. */
118 u64 start; /* Real start (aligned to blk_size). */
119 u64 end; /* Real end, trimmed if needed. */
120 u64 count; /* Count of objects in space. */
121 u64 blks; /* Count of blks in the space. */
122 u64 max_order; /* Specific maximum order. */
123
124 struct rb_root alloced_buddies; /* Outstanding allocations. */
125 struct rb_root fixed_allocs; /* Outstanding fixed allocations. */
126
127 struct list_head co_list;
128
129 /*
130 * Impose an upper bound on the maximum order.
131 */
132#define GPU_BALLOC_ORDER_LIST_LEN (GPU_BALLOC_MAX_ORDER + 1)
133
134 struct list_head buddy_list[GPU_BALLOC_ORDER_LIST_LEN];
135 u64 buddy_list_len[GPU_BALLOC_ORDER_LIST_LEN];
136 u64 buddy_list_split[GPU_BALLOC_ORDER_LIST_LEN];
137 u64 buddy_list_alloced[GPU_BALLOC_ORDER_LIST_LEN];
138
139 /*
140 * This is for when the allocator is managing a GVA space (the
141 * GPU_ALLOC_GVA_SPACE bit is set in @flags). This requires
142 * that we group like sized allocations into PDE blocks.
143 */
144 u64 pte_blk_order;
145
146 int initialized;
147 int alloc_made; /* True after the first alloc. */
148
149 u64 flags;
150
151 u64 bytes_alloced;
152 u64 bytes_alloced_real;
153 u64 bytes_freed;
154};
155
156static inline struct nvgpu_buddy_allocator *buddy_allocator(
157 struct nvgpu_allocator *a)
158{
159 return (struct nvgpu_buddy_allocator *)(a)->priv;
160}
161
162static inline struct list_head *balloc_get_order_list(
163 struct nvgpu_buddy_allocator *a, int order)
164{
165 return &a->buddy_list[order];
166}
167
168static inline u64 balloc_order_to_len(struct nvgpu_buddy_allocator *a,
169 int order)
170{
171 return (1 << order) * a->blk_size;
172}
173
174static inline u64 balloc_base_shift(struct nvgpu_buddy_allocator *a,
175 u64 base)
176{
177 return base - a->start;
178}
179
180static inline u64 balloc_base_unshift(struct nvgpu_buddy_allocator *a,
181 u64 base)
182{
183 return base + a->start;
184}
185
186static inline struct nvgpu_allocator *balloc_owner(
187 struct nvgpu_buddy_allocator *a)
188{
189 return a->owner;
190}
191
192#endif