summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/buddy_allocator_priv.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/buddy_allocator_priv.h')
-rw-r--r--drivers/gpu/nvgpu/gk20a/buddy_allocator_priv.h190
1 files changed, 190 insertions, 0 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/buddy_allocator_priv.h b/drivers/gpu/nvgpu/gk20a/buddy_allocator_priv.h
new file mode 100644
index 00000000..bed0492c
--- /dev/null
+++ b/drivers/gpu/nvgpu/gk20a/buddy_allocator_priv.h
@@ -0,0 +1,190 @@
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 gk20a_allocator;
24struct vm_gk20a;
25
26/*
27 * Each buddy is an element in a binary tree.
28 */
29struct gk20a_buddy {
30 struct gk20a_buddy *parent; /* Parent node. */
31 struct gk20a_buddy *buddy; /* This node's buddy. */
32 struct gk20a_buddy *left; /* Lower address sub-node. */
33 struct gk20a_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.
50 */
51#define BALLOC_PTE_SIZE_ANY 0x0
52#define BALLOC_PTE_SIZE_SMALL 0x1
53#define BALLOC_PTE_SIZE_BIG 0x2
54 int pte_size;
55};
56
57#define __buddy_flag_ops(flag, flag_up) \
58 static inline int buddy_is_ ## flag(struct gk20a_buddy *b) \
59 { \
60 return b->flags & BALLOC_BUDDY_ ## flag_up; \
61 } \
62 static inline void buddy_set_ ## flag(struct gk20a_buddy *b) \
63 { \
64 b->flags |= BALLOC_BUDDY_ ## flag_up; \
65 } \
66 static inline void buddy_clr_ ## flag(struct gk20a_buddy *b) \
67 { \
68 b->flags &= ~BALLOC_BUDDY_ ## flag_up; \
69 }
70
71/*
72 * int buddy_is_alloced(struct gk20a_buddy *b);
73 * void buddy_set_alloced(struct gk20a_buddy *b);
74 * void buddy_clr_alloced(struct gk20a_buddy *b);
75 *
76 * int buddy_is_split(struct gk20a_buddy *b);
77 * void buddy_set_split(struct gk20a_buddy *b);
78 * void buddy_clr_split(struct gk20a_buddy *b);
79 *
80 * int buddy_is_in_list(struct gk20a_buddy *b);
81 * void buddy_set_in_list(struct gk20a_buddy *b);
82 * void buddy_clr_in_list(struct gk20a_buddy *b);
83 */
84__buddy_flag_ops(alloced, ALLOCED);
85__buddy_flag_ops(split, SPLIT);
86__buddy_flag_ops(in_list, IN_LIST);
87
88/*
89 * Keeps info for a fixed allocation.
90 */
91struct gk20a_fixed_alloc {
92 struct list_head buddies; /* List of buddies. */
93 struct rb_node alloced_entry; /* RB tree of fixed allocations. */
94
95 u64 start; /* Start of fixed block. */
96 u64 end; /* End address. */
97};
98
99/*
100 * GPU buddy allocator for the various GPU address spaces. Each addressable unit
101 * doesn't have to correspond to a byte. In some cases each unit is a more
102 * complex object such as a comp_tag line or the like.
103 *
104 * The max order is computed based on the size of the minimum order and the size
105 * of the address space.
106 *
107 * order_size is the size of an order 0 buddy.
108 */
109struct gk20a_buddy_allocator {
110 struct gk20a_allocator *owner; /* Owner of this buddy allocator. */
111 struct vm_gk20a *vm; /* Parent VM - can be NULL. */
112
113 u64 base; /* Base address of the space. */
114 u64 length; /* Length of the space. */
115 u64 blk_size; /* Size of order 0 allocation. */
116 u64 blk_shift; /* Shift to divide by blk_size. */
117
118 /* Internal stuff. */
119 u64 start; /* Real start (aligned to blk_size). */
120 u64 end; /* Real end, trimmed if needed. */
121 u64 count; /* Count of objects in space. */
122 u64 blks; /* Count of blks in the space. */
123 u64 max_order; /* Specific maximum order. */
124
125 struct rb_root alloced_buddies; /* Outstanding allocations. */
126 struct rb_root fixed_allocs; /* Outstanding fixed allocations. */
127
128 /*
129 * Impose an upper bound on the maximum order.
130 */
131#define GPU_BALLOC_ORDER_LIST_LEN (GPU_BALLOC_MAX_ORDER + 1)
132
133 struct list_head buddy_list[GPU_BALLOC_ORDER_LIST_LEN];
134 u64 buddy_list_len[GPU_BALLOC_ORDER_LIST_LEN];
135 u64 buddy_list_split[GPU_BALLOC_ORDER_LIST_LEN];
136 u64 buddy_list_alloced[GPU_BALLOC_ORDER_LIST_LEN];
137
138 /*
139 * This is for when the allocator is managing a GVA space (the
140 * GPU_BALLOC_GVA_SPACE bit is set in @flags). This requires
141 * that we group like sized allocations into PDE blocks.
142 */
143 u64 pte_blk_order;
144
145 int initialized;
146
147 u64 flags;
148
149 u64 bytes_alloced;
150 u64 bytes_alloced_real;
151 u64 bytes_freed;
152};
153
154static inline struct gk20a_buddy_allocator *buddy_allocator(
155 struct gk20a_allocator *a)
156{
157 return (struct gk20a_buddy_allocator *)(a)->priv;
158}
159
160static inline struct list_head *balloc_get_order_list(
161 struct gk20a_buddy_allocator *a, int order)
162{
163 return &a->buddy_list[order];
164}
165
166static inline u64 balloc_order_to_len(struct gk20a_buddy_allocator *a,
167 int order)
168{
169 return (1 << order) * a->blk_size;
170}
171
172static inline u64 balloc_base_shift(struct gk20a_buddy_allocator *a,
173 u64 base)
174{
175 return base - a->start;
176}
177
178static inline u64 balloc_base_unshift(struct gk20a_buddy_allocator *a,
179 u64 base)
180{
181 return base + a->start;
182}
183
184static inline struct gk20a_allocator *balloc_owner(
185 struct gk20a_buddy_allocator *a)
186{
187 return a->owner;
188}
189
190#endif