summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/include
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/nvgpu/include')
-rw-r--r--drivers/gpu/nvgpu/include/nvgpu/kmem.h223
-rw-r--r--drivers/gpu/nvgpu/include/nvgpu/kmem_linux.h123
2 files changed, 324 insertions, 22 deletions
diff --git a/drivers/gpu/nvgpu/include/nvgpu/kmem.h b/drivers/gpu/nvgpu/include/nvgpu/kmem.h
index c08e40a6..59192525 100644
--- a/drivers/gpu/nvgpu/include/nvgpu/kmem.h
+++ b/drivers/gpu/nvgpu/include/nvgpu/kmem.h
@@ -14,18 +14,21 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */ 15 */
16 16
17#ifndef NVGPU_KMEM_H 17#ifndef __NVGPU_KMEM_H__
18#define NVGPU_KMEM_H 18#define __NVGPU_KMEM_H__
19 19
20#include <linux/mm.h> 20/*
21#include <linux/slab.h> 21 * Incase this isn't defined already.
22#include <linux/vmalloc.h> 22 */
23 23#ifndef _THIS_IP_
24#include <asm/page.h> 24#define _THIS_IP_ ({ __label__ __here; __here: (unsigned long)&&__here; })
25#endif
25 26
26struct gk20a; 27struct gk20a;
27 28
28/* 29/**
30 * DOC: Kmem cache support
31 *
29 * In Linux there is support for the notion of a kmem_cache. It gives better 32 * In Linux there is support for the notion of a kmem_cache. It gives better
30 * memory usage characteristics for lots of allocations of the same size. Think 33 * memory usage characteristics for lots of allocations of the same size. Think
31 * structs that get allocated over and over. Normal kmalloc() type routines 34 * structs that get allocated over and over. Normal kmalloc() type routines
@@ -37,26 +40,200 @@ struct gk20a;
37 */ 40 */
38struct nvgpu_kmem_cache; 41struct nvgpu_kmem_cache;
39 42
43#ifdef CONFIG_NVGPU_TRACK_MEM_USAGE
44/*
45 * Uncomment this if you want to enable stack traces in the memory profiling.
46 * Since this is a fairly high overhead operation and is only necessary for
47 * debugging actual bugs it's left here for developers to enable.
48 */
49/* #define __NVGPU_SAVE_KALLOC_STACK_TRACES */
50
51/*
52 * Defined per-OS.
53 */
54struct nvgpu_mem_alloc_tracker;
55#endif
56
57
58/**
59 * nvgpu_kmem_cache_create - create an nvgpu kernel memory cache.
60 *
61 * @g The GPU driver struct using this cache.
62 * @size Size of the object allocated by the cache.
63 *
64 * This cache can be used to allocate objects of size @size. Common usage would
65 * be for a struct that gets allocated a lot. In that case @size should be
66 * sizeof(struct my_struct).
67 *
68 * A given implementation of this need not do anything special. The allocation
69 * routines can simply be passed on to nvgpu_kzalloc() if desired so packing
70 * and alignment of the structs cannot be assumed.
71 */
40struct nvgpu_kmem_cache *nvgpu_kmem_cache_create(struct gk20a *g, size_t size); 72struct nvgpu_kmem_cache *nvgpu_kmem_cache_create(struct gk20a *g, size_t size);
73
74/**
75 * nvgpu_kmem_cache_destroy - destroy a cache created by
76 * nvgpu_kmem_cache_create().
77 *
78 * @cache The cache to destroy.
79 */
41void nvgpu_kmem_cache_destroy(struct nvgpu_kmem_cache *cache); 80void nvgpu_kmem_cache_destroy(struct nvgpu_kmem_cache *cache);
42 81
82/**
83 * nvgpu_kmem_cache_alloc - Allocate an object from the cache
84 *
85 * @cache The cache to alloc from.
86 */
43void *nvgpu_kmem_cache_alloc(struct nvgpu_kmem_cache *cache); 87void *nvgpu_kmem_cache_alloc(struct nvgpu_kmem_cache *cache);
88
89/**
90 * nvgpu_kmem_cache_free - Free an object back to a cache
91 *
92 * @cache The cache to return the object to.
93 * @ptr Pointer to the object to free.
94 */
44void nvgpu_kmem_cache_free(struct nvgpu_kmem_cache *cache, void *ptr); 95void nvgpu_kmem_cache_free(struct nvgpu_kmem_cache *cache, void *ptr);
45 96
46static inline void *__nvgpu_big_alloc(size_t size, bool clear) 97/**
98 * nvgpu_kmalloc - Allocate from the kernel's allocator.
99 *
100 * @g: Current GPU.
101 * @size: Size of the allocation.
102 *
103 * Allocate a chunk of system memory from the kernel. Allocations larger than 1
104 * page may fail even when there may appear to be enough memory.
105 *
106 * This function may sleep so cannot be used in IRQs.
107 */
108#define nvgpu_kmalloc(g, size) __nvgpu_kmalloc(g, size, _THIS_IP_)
109
110/**
111 * nvgpu_kzalloc - Allocate from the kernel's allocator.
112 *
113 * @g: Current GPU.
114 * @size: Size of the allocation.
115 *
116 * Identical to nvgpu_kalloc() except the memory will be zeroed before being
117 * returned.
118 */
119#define nvgpu_kzalloc(g, size) __nvgpu_kzalloc(g, size, _THIS_IP_)
120
121/**
122 * nvgpu_kcalloc - Allocate from the kernel's allocator.
123 *
124 * @g: Current GPU.
125 * @n: Number of objects.
126 * @size: Size of each object.
127 *
128 * Identical to nvgpu_kalloc() except the size of the memory chunk returned is
129 * @n * @size.
130 */
131#define nvgpu_kcalloc(g, n, size) __nvgpu_kcalloc(g, n, size, _THIS_IP_)
132
133/**
134 * nvgpu_vmalloc - Allocate memory and return a map to it.
135 *
136 * @g: Current GPU.
137 * @size: Size of the allocation.
138 *
139 * Allocate some memory and return a pointer to a virtual memory mapping of
140 * that memory in the kernel's virtual address space. The underlying physical
141 * memory is not guaranteed to be contiguous (and indeed likely isn't). This
142 * allows for much larger allocations to be done without worrying about as much
143 * about physical memory fragmentation.
144 *
145 * This function may sleep.
146 */
147#define nvgpu_vmalloc(g, size) __nvgpu_vmalloc(g, size, _THIS_IP_)
148
149/**
150 * nvgpu_vzalloc - Allocate memory and return a map to it.
151 *
152 * @g: Current GPU.
153 * @size: Size of the allocation.
154 *
155 * Identical to nvgpu_vmalloc() except this will return zero'ed memory.
156 */
157#define nvgpu_vzalloc(g, size) __nvgpu_vzalloc(g, size, _THIS_IP_)
158
159/**
160 * nvgpu_kfree - Frees an alloc from nvgpu_kmalloc, nvgpu_kzalloc,
161 * nvgpu_kcalloc.
162 *
163 * @g: Current GPU.
164 * @addr: Address of object to free.
165 */
166#define nvgpu_kfree(g, addr) __nvgpu_kfree(g, addr)
167
168/**
169 * nvgpu_vfree - Frees an alloc from nvgpu_vmalloc, nvgpu_vzalloc.
170 *
171 * @g: Current GPU.
172 * @addr: Address of object to free.
173 */
174#define nvgpu_vfree(g, addr) __nvgpu_vfree(g, addr)
175
176#define kmem_dbg(fmt, args...) \
177 gk20a_dbg(gpu_dbg_kmem, fmt, ##args)
178
179/**
180 * nvgpu_kmem_init - Initialize the kmem tracking stuff.
181 *
182 *@g: The driver to init.
183 *
184 * Returns non-zero on failure.
185 */
186int nvgpu_kmem_init(struct gk20a *g);
187
188/**
189 * nvgpu_kmem_fini - Finalize the kmem tracking code
190 *
191 * @g - The GPU.
192 * @flags - Flags that control operation of this finalization.
193 *
194 * Cleanup resources used by nvgpu_kmem. Available flags for cleanup are:
195 *
196 * %NVGPU_KMEM_FINI_DO_NOTHING
197 * %NVGPU_KMEM_FINI_FORCE_CLEANUP
198 * %NVGPU_KMEM_FINI_DUMP_ALLOCS
199 * %NVGPU_KMEM_FINI_WARN
200 * %NVGPU_KMEM_FINI_BUG
201 *
202 * %NVGPU_KMEM_FINI_DO_NOTHING will be overridden by anything else specified.
203 * Put another way don't just add %NVGPU_KMEM_FINI_DO_NOTHING and expect that
204 * to suppress other flags from doing anything.
205 */
206void nvgpu_kmem_fini(struct gk20a *g, int flags);
207
208/*
209 * These will simply be ignored if CONFIG_NVGPU_TRACK_MEM_USAGE is not defined.
210 */
211#define NVGPU_KMEM_FINI_DO_NOTHING 0
212#define NVGPU_KMEM_FINI_FORCE_CLEANUP (1 << 0)
213#define NVGPU_KMEM_FINI_DUMP_ALLOCS (1 << 1)
214#define NVGPU_KMEM_FINI_WARN (1 << 2)
215#define NVGPU_KMEM_FINI_BUG (1 << 3)
216
217/*
218 * When there's other implementations make sure they are included instead of
219 * Linux when not compiling on Linux!
220 */
221#include <nvgpu/kmem_linux.h>
222
223static inline void *__nvgpu_big_alloc(struct gk20a *g, size_t size, bool clear)
47{ 224{
48 void *p; 225 void *p;
49 226
50 if (size > PAGE_SIZE) { 227 if (size > PAGE_SIZE) {
51 if (clear) 228 if (clear)
52 p = vzalloc(size); 229 p = nvgpu_vzalloc(g, size);
53 else 230 else
54 p = vmalloc(size); 231 p = nvgpu_vmalloc(g, size);
55 } else { 232 } else {
56 if (clear) 233 if (clear)
57 p = kzalloc(size, GFP_KERNEL); 234 p = nvgpu_kzalloc(g, size);
58 else 235 else
59 p = kmalloc(size, GFP_KERNEL); 236 p = nvgpu_kmalloc(g, size);
60 } 237 }
61 238
62 return p; 239 return p;
@@ -65,6 +242,7 @@ static inline void *__nvgpu_big_alloc(size_t size, bool clear)
65/** 242/**
66 * nvgpu_big_malloc - Pick virtual or physical alloc based on @size 243 * nvgpu_big_malloc - Pick virtual or physical alloc based on @size
67 * 244 *
245 * @g - The GPU.
68 * @size - Size of the allocation. 246 * @size - Size of the allocation.
69 * 247 *
70 * On some platforms (i.e Linux) it is possible to allocate memory directly 248 * On some platforms (i.e Linux) it is possible to allocate memory directly
@@ -83,30 +261,31 @@ static inline void *__nvgpu_big_alloc(size_t size, bool clear)
83 * Returns a pointer to a virtual address range that the kernel can access or 261 * Returns a pointer to a virtual address range that the kernel can access or
84 * %NULL on failure. 262 * %NULL on failure.
85 */ 263 */
86static inline void *nvgpu_big_malloc(size_t size) 264static inline void *nvgpu_big_malloc(struct gk20a *g, size_t size)
87{ 265{
88 return __nvgpu_big_alloc(size, false); 266 return __nvgpu_big_alloc(g, size, false);
89} 267}
90 268
91/** 269/**
92 * nvgpu_big_malloc - Pick virtual or physical alloc based on @size 270 * nvgpu_big_malloc - Pick virtual or physical alloc based on @size
93 * 271 *
272 * @g - The GPU.
94 * @size - Size of the allocation. 273 * @size - Size of the allocation.
95 * 274 *
96 * Zeroed memory version of nvgpu_big_malloc(). 275 * Zeroed memory version of nvgpu_big_malloc().
97 */ 276 */
98static inline void *nvgpu_big_zalloc(size_t size) 277static inline void *nvgpu_big_zalloc(struct gk20a *g, size_t size)
99{ 278{
100 return __nvgpu_big_alloc(size, true); 279 return __nvgpu_big_alloc(g, size, true);
101} 280}
102 281
103/** 282/**
104 * nvgpu_big_free - Free and alloc from nvgpu_big_zalloc() or 283 * nvgpu_big_free - Free and alloc from nvgpu_big_zalloc() or
105 * nvgpu_big_malloc(). 284 * nvgpu_big_malloc().
106 * 285 * @g - The GPU.
107 * @p - A pointer allocated by nvgpu_big_zalloc() or nvgpu_big_malloc(). 286 * @p - A pointer allocated by nvgpu_big_zalloc() or nvgpu_big_malloc().
108 */ 287 */
109static inline void nvgpu_big_free(void *p) 288static inline void nvgpu_big_free(struct gk20a *g, void *p)
110{ 289{
111 /* 290 /*
112 * This will have to be fixed eventually. Allocs that use 291 * This will have to be fixed eventually. Allocs that use
@@ -114,9 +293,9 @@ static inline void nvgpu_big_free(void *p)
114 * when freeing. 293 * when freeing.
115 */ 294 */
116 if (virt_addr_valid(p)) 295 if (virt_addr_valid(p))
117 kfree(p); 296 nvgpu_kfree(g, p);
118 else 297 else
119 vfree(p); 298 nvgpu_vfree(g, p);
120} 299}
121 300
122#endif 301#endif /* __NVGPU_KMEM_H__ */
diff --git a/drivers/gpu/nvgpu/include/nvgpu/kmem_linux.h b/drivers/gpu/nvgpu/include/nvgpu/kmem_linux.h
new file mode 100644
index 00000000..d1cd27f3
--- /dev/null
+++ b/drivers/gpu/nvgpu/include/nvgpu/kmem_linux.h
@@ -0,0 +1,123 @@
1/*
2 * Copyright (c) 2017, 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 __NVGPU_KMEM_LINUX_H__
18#define __NVGPU_KMEM_LINUX_H__
19
20#include <linux/mm.h>
21#include <linux/slab.h>
22#include <linux/vmalloc.h>
23
24#include <asm/page.h>
25
26struct gk20a;
27struct device;
28
29#ifdef CONFIG_NVGPU_TRACK_MEM_USAGE
30void *__nvgpu_track_vmalloc(struct gk20a *g, unsigned long size,
31 unsigned long ip);
32void *__nvgpu_track_vzalloc(struct gk20a *g, unsigned long size,
33 unsigned long ip);
34void *__nvgpu_track_kmalloc(struct gk20a *g, size_t size, unsigned long ip);
35void *__nvgpu_track_kzalloc(struct gk20a *g, size_t size, unsigned long ip);
36void *__nvgpu_track_kcalloc(struct gk20a *g, size_t n, size_t size,
37 unsigned long ip);
38void __nvgpu_track_vfree(struct gk20a *g, void *addr);
39void __nvgpu_track_kfree(struct gk20a *g, void *addr);
40
41void nvgpu_kmem_debugfs_init(struct device *dev);
42#else
43static inline void nvgpu_kmem_debugfs_init(struct device *dev)
44{
45}
46#endif
47
48/**
49 * DOC: Linux pass through kmem implementation.
50 *
51 * These are the Linux implementations of the various kmem functions defined by
52 * nvgpu. This should not be included directly - instead include <nvgpu/kmem.h>.
53 */
54
55static inline void *__nvgpu_kmalloc(struct gk20a *g, unsigned long size,
56 unsigned long ip)
57{
58#ifdef CONFIG_NVGPU_TRACK_MEM_USAGE
59 return __nvgpu_track_vmalloc(g, size, ip);
60#else
61 return kmalloc(size, GFP_KERNEL);
62#endif
63}
64
65static inline void *__nvgpu_kzalloc(struct gk20a *g, size_t size,
66 unsigned long ip)
67{
68#ifdef CONFIG_NVGPU_TRACK_MEM_USAGE
69 return __nvgpu_track_kzalloc(g, size, ip);
70#else
71 return kzalloc(size, GFP_KERNEL);
72#endif
73}
74
75static inline void *__nvgpu_kcalloc(struct gk20a *g, size_t n, size_t size,
76 unsigned long ip)
77{
78#ifdef CONFIG_NVGPU_TRACK_MEM_USAGE
79 return __nvgpu_track_kcalloc(g, n, size, ip);
80#else
81 return kcalloc(n, size, GFP_KERNEL);
82#endif
83}
84
85static inline void *__nvgpu_vmalloc(struct gk20a *g, unsigned long size,
86 unsigned long ip)
87{
88#ifdef CONFIG_NVGPU_TRACK_MEM_USAGE
89 return __nvgpu_track_vmalloc(g, size, ip);
90#else
91 return vmalloc(size);
92#endif
93}
94
95static inline void *__nvgpu_vzalloc(struct gk20a *g, unsigned long size,
96 unsigned long ip)
97{
98#ifdef CONFIG_NVGPU_TRACK_MEM_USAGE
99 return __nvgpu_track_vzalloc(g, size, ip);
100#else
101 return vzalloc(size);
102#endif
103}
104
105static inline void __nvgpu_kfree(struct gk20a *g, void *addr)
106{
107#ifdef CONFIG_NVGPU_TRACK_MEM_USAGE
108 __nvgpu_track_kfree(g, addr);
109#else
110 kfree(addr);
111#endif
112}
113
114static inline void __nvgpu_vfree(struct gk20a *g, void *addr)
115{
116#ifdef CONFIG_NVGPU_TRACK_MEM_USAGE
117 __nvgpu_track_vfree(g, addr);
118#else
119 vfree(addr);
120#endif
121}
122
123#endif