summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/common
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/nvgpu/common')
-rw-r--r--drivers/gpu/nvgpu/common/linux/ioctl_ctrl.c8
-rw-r--r--drivers/gpu/nvgpu/common/linux/vidmem.c80
-rw-r--r--drivers/gpu/nvgpu/common/linux/vm.c1
-rw-r--r--drivers/gpu/nvgpu/common/mm/vidmem.c80
4 files changed, 117 insertions, 52 deletions
diff --git a/drivers/gpu/nvgpu/common/linux/ioctl_ctrl.c b/drivers/gpu/nvgpu/common/linux/ioctl_ctrl.c
index 7180256a..30988462 100644
--- a/drivers/gpu/nvgpu/common/linux/ioctl_ctrl.c
+++ b/drivers/gpu/nvgpu/common/linux/ioctl_ctrl.c
@@ -26,6 +26,9 @@
26#include <nvgpu/bug.h> 26#include <nvgpu/bug.h>
27#include <nvgpu/bus.h> 27#include <nvgpu/bus.h>
28#include <nvgpu/vidmem.h> 28#include <nvgpu/vidmem.h>
29#include <nvgpu/log.h>
30
31#include <nvgpu/linux/vidmem.h>
29 32
30#include "ioctl_ctrl.h" 33#include "ioctl_ctrl.h"
31#include "ioctl_tsg.h" 34#include "ioctl_tsg.h"
@@ -33,9 +36,8 @@
33#include "gk20a/gk20a.h" 36#include "gk20a/gk20a.h"
34#include "gk20a/platform_gk20a.h" 37#include "gk20a/platform_gk20a.h"
35#include "gk20a/fence_gk20a.h" 38#include "gk20a/fence_gk20a.h"
36#include "os_linux.h"
37 39
38#include <nvgpu/log.h> 40#include "os_linux.h"
39 41
40#define HZ_TO_MHZ(a) ((a > 0xF414F9CD7ULL) ? 0xffff : (a >> 32) ? \ 42#define HZ_TO_MHZ(a) ((a > 0xF414F9CD7ULL) ? 0xffff : (a >> 32) ? \
41 (u32) ((a * 0x10C8ULL) >> 32) : (u16) ((u32) a/MHZ)) 43 (u32) ((a * 0x10C8ULL) >> 32) : (u16) ((u32) a/MHZ))
@@ -693,7 +695,7 @@ static int nvgpu_gpu_alloc_vidmem(struct gk20a *g,
693 return -EINVAL; 695 return -EINVAL;
694 } 696 }
695 697
696 fd = nvgpu_vidmem_buf_alloc(g, args->in.size); 698 fd = nvgpu_vidmem_export_linux(g, args->in.size);
697 if (fd < 0) 699 if (fd < 0)
698 return fd; 700 return fd;
699 701
diff --git a/drivers/gpu/nvgpu/common/linux/vidmem.c b/drivers/gpu/nvgpu/common/linux/vidmem.c
index 5d47c858..ea8e552f 100644
--- a/drivers/gpu/nvgpu/common/linux/vidmem.c
+++ b/drivers/gpu/nvgpu/common/linux/vidmem.c
@@ -25,6 +25,7 @@
25#include <nvgpu/page_allocator.h> 25#include <nvgpu/page_allocator.h>
26 26
27#include <nvgpu/linux/dma.h> 27#include <nvgpu/linux/dma.h>
28#include <nvgpu/linux/vidmem.h>
28 29
29#include "gk20a/gk20a.h" 30#include "gk20a/gk20a.h"
30#include "gk20a/mm_gk20a.h" 31#include "gk20a/mm_gk20a.h"
@@ -73,14 +74,16 @@ static void gk20a_vidbuf_unmap_dma_buf(struct dma_buf_attachment *attach,
73static void gk20a_vidbuf_release(struct dma_buf *dmabuf) 74static void gk20a_vidbuf_release(struct dma_buf *dmabuf)
74{ 75{
75 struct nvgpu_vidmem_buf *buf = dmabuf->priv; 76 struct nvgpu_vidmem_buf *buf = dmabuf->priv;
77 struct nvgpu_vidmem_linux *linux_buf = buf->priv;
78 struct gk20a *g = buf->g;
76 79
77 gk20a_dbg_fn(""); 80 gk20a_dbg_fn("");
78 81
79 if (buf->dmabuf_priv) 82 if (linux_buf && linux_buf->dmabuf_priv_delete)
80 buf->dmabuf_priv_delete(buf->dmabuf_priv); 83 linux_buf->dmabuf_priv_delete(linux_buf->dmabuf_priv);
81 84
82 nvgpu_dma_free(buf->g, buf->mem); 85 nvgpu_kfree(g, linux_buf);
83 nvgpu_kfree(buf->g, buf); 86 nvgpu_vidmem_buf_free(g, buf);
84} 87}
85 88
86static void *gk20a_vidbuf_kmap(struct dma_buf *dmabuf, unsigned long page_num) 89static void *gk20a_vidbuf_kmap(struct dma_buf *dmabuf, unsigned long page_num)
@@ -105,9 +108,10 @@ static int gk20a_vidbuf_set_private(struct dma_buf *dmabuf,
105 struct device *dev, void *priv, void (*delete)(void *priv)) 108 struct device *dev, void *priv, void (*delete)(void *priv))
106{ 109{
107 struct nvgpu_vidmem_buf *buf = dmabuf->priv; 110 struct nvgpu_vidmem_buf *buf = dmabuf->priv;
111 struct nvgpu_vidmem_linux *linux_buf = buf->priv;
108 112
109 buf->dmabuf_priv = priv; 113 linux_buf->dmabuf_priv = priv;
110 buf->dmabuf_priv_delete = delete; 114 linux_buf->dmabuf_priv_delete = delete;
111 115
112 return 0; 116 return 0;
113} 117}
@@ -116,8 +120,9 @@ static void *gk20a_vidbuf_get_private(struct dma_buf *dmabuf,
116 struct device *dev) 120 struct device *dev)
117{ 121{
118 struct nvgpu_vidmem_buf *buf = dmabuf->priv; 122 struct nvgpu_vidmem_buf *buf = dmabuf->priv;
123 struct nvgpu_vidmem_linux *linux_buf = buf->priv;
119 124
120 return buf->dmabuf_priv; 125 return linux_buf->dmabuf_priv;
121} 126}
122 127
123static const struct dma_buf_ops gk20a_vidbuf_ops = { 128static const struct dma_buf_ops gk20a_vidbuf_ops = {
@@ -153,66 +158,45 @@ struct gk20a *nvgpu_vidmem_buf_owner(struct dma_buf *dmabuf)
153 return buf->g; 158 return buf->g;
154} 159}
155 160
156int nvgpu_vidmem_buf_alloc(struct gk20a *g, size_t bytes) 161int nvgpu_vidmem_export_linux(struct gk20a *g, size_t bytes)
157{ 162{
158 struct nvgpu_vidmem_buf *buf; 163 struct nvgpu_vidmem_buf *buf;
159 int err = 0, fd; 164 struct nvgpu_vidmem_linux *priv;
165 int err, fd;
160 166
161 gk20a_dbg_fn(""); 167 priv = nvgpu_kzalloc(g, sizeof(*priv));
162 168 if (!priv)
163 buf = nvgpu_kzalloc(g, sizeof(*buf));
164 if (!buf)
165 return -ENOMEM; 169 return -ENOMEM;
166 170
167 buf->g = g; 171 buf = nvgpu_vidmem_user_alloc(g, bytes);
168 172 if (!buf) {
169 if (!g->mm.vidmem.cleared) { 173 err = -ENOMEM;
170 nvgpu_mutex_acquire(&g->mm.vidmem.first_clear_mutex); 174 goto fail;
171 if (!g->mm.vidmem.cleared) {
172 err = nvgpu_vidmem_clear_all(g);
173 if (err) {
174 nvgpu_err(g,
175 "failed to clear whole vidmem");
176 goto err_kfree;
177 }
178 }
179 nvgpu_mutex_release(&g->mm.vidmem.first_clear_mutex);
180 } 175 }
181 176
182 buf->mem = nvgpu_kzalloc(g, sizeof(struct nvgpu_mem)); 177 priv->dmabuf = gk20a_vidbuf_export(buf);
183 if (!buf->mem) 178 if (IS_ERR(priv->dmabuf)) {
184 goto err_kfree; 179 err = PTR_ERR(priv->dmabuf);
185 180 goto fail;
186 buf->mem->mem_flags |= NVGPU_MEM_FLAG_USER_MEM;
187
188 err = nvgpu_dma_alloc_vid(g, bytes, buf->mem);
189 if (err)
190 goto err_memfree;
191
192 buf->dmabuf = gk20a_vidbuf_export(buf);
193 if (IS_ERR(buf->dmabuf)) {
194 err = PTR_ERR(buf->dmabuf);
195 goto err_bfree;
196 } 181 }
197 182
183 buf->priv = priv;
184
198 fd = tegra_alloc_fd(current->files, 1024, O_RDWR); 185 fd = tegra_alloc_fd(current->files, 1024, O_RDWR);
199 if (fd < 0) { 186 if (fd < 0) {
200 /* ->release frees what we have done */ 187 /* ->release frees what we have done */
201 dma_buf_put(buf->dmabuf); 188 dma_buf_put(priv->dmabuf);
202 return fd; 189 return fd;
203 } 190 }
204 191
205 /* fclose() on this drops one ref, freeing the dma buf */ 192 /* fclose() on this drops one ref, freeing the dma buf */
206 fd_install(fd, buf->dmabuf->file); 193 fd_install(fd, priv->dmabuf->file);
207 194
208 return fd; 195 return fd;
209 196
210err_bfree: 197fail:
211 nvgpu_dma_free(g, buf->mem); 198 nvgpu_kfree(g, priv);
212err_memfree: 199 nvgpu_vidmem_buf_free(g, buf);
213 nvgpu_kfree(g, buf->mem);
214err_kfree:
215 nvgpu_kfree(g, buf);
216 return err; 200 return err;
217} 201}
218 202
diff --git a/drivers/gpu/nvgpu/common/linux/vm.c b/drivers/gpu/nvgpu/common/linux/vm.c
index d0f87148..45058321 100644
--- a/drivers/gpu/nvgpu/common/linux/vm.c
+++ b/drivers/gpu/nvgpu/common/linux/vm.c
@@ -26,6 +26,7 @@
26#include <nvgpu/vidmem.h> 26#include <nvgpu/vidmem.h>
27#include <nvgpu/enabled.h> 27#include <nvgpu/enabled.h>
28 28
29#include <nvgpu/linux/vidmem.h>
29#include <nvgpu/linux/nvgpu_mem.h> 30#include <nvgpu/linux/nvgpu_mem.h>
30 31
31#include "gk20a/gk20a.h" 32#include "gk20a/gk20a.h"
diff --git a/drivers/gpu/nvgpu/common/mm/vidmem.c b/drivers/gpu/nvgpu/common/mm/vidmem.c
index c95cedec..18f46c03 100644
--- a/drivers/gpu/nvgpu/common/mm/vidmem.c
+++ b/drivers/gpu/nvgpu/common/mm/vidmem.c
@@ -22,6 +22,7 @@
22 22
23#include <linux/scatterlist.h> 23#include <linux/scatterlist.h>
24 24
25#include <nvgpu/dma.h>
25#include <nvgpu/vidmem.h> 26#include <nvgpu/vidmem.h>
26#include <nvgpu/page_allocator.h> 27#include <nvgpu/page_allocator.h>
27 28
@@ -34,7 +35,7 @@ void nvgpu_vidmem_destroy(struct gk20a *g)
34 nvgpu_alloc_destroy(&g->mm.vidmem.allocator); 35 nvgpu_alloc_destroy(&g->mm.vidmem.allocator);
35} 36}
36 37
37int nvgpu_vidmem_clear_all(struct gk20a *g) 38static int __nvgpu_vidmem_do_clear_all(struct gk20a *g)
38{ 39{
39 struct mm_gk20a *mm = &g->mm; 40 struct mm_gk20a *mm = &g->mm;
40 struct gk20a_fence *gk20a_fence_out = NULL; 41 struct gk20a_fence *gk20a_fence_out = NULL;
@@ -257,3 +258,80 @@ struct nvgpu_mem *nvgpu_vidmem_get_pending_alloc(struct mm_gk20a *mm)
257 258
258 return mem; 259 return mem;
259} 260}
261
262static int nvgpu_vidmem_clear_all(struct gk20a *g)
263{
264 int err;
265
266 if (g->mm.vidmem.cleared)
267 return 0;
268
269 nvgpu_mutex_acquire(&g->mm.vidmem.first_clear_mutex);
270 if (!g->mm.vidmem.cleared) {
271 err = __nvgpu_vidmem_do_clear_all(g);
272 if (err) {
273 nvgpu_mutex_release(&g->mm.vidmem.first_clear_mutex);
274 nvgpu_err(g, "failed to clear whole vidmem");
275 return err;
276 }
277 }
278 nvgpu_mutex_release(&g->mm.vidmem.first_clear_mutex);
279
280 return 0;
281}
282
283struct nvgpu_vidmem_buf *nvgpu_vidmem_user_alloc(struct gk20a *g, size_t bytes)
284{
285 struct nvgpu_vidmem_buf *buf;
286 int err;
287
288 err = nvgpu_vidmem_clear_all(g);
289 if (err)
290 return NULL;
291
292 buf = nvgpu_kzalloc(g, sizeof(*buf));
293 if (!buf)
294 return NULL;
295
296 buf->g = g;
297 buf->mem = nvgpu_kzalloc(g, sizeof(*buf->mem));
298 if (!buf->mem)
299 goto fail;
300
301 err = nvgpu_dma_alloc_vid(g, bytes, buf->mem);
302 if (err)
303 goto fail;
304
305 /*
306 * Alerts the DMA API that when we free this vidmem buf we have to
307 * clear it to avoid leaking data to userspace.
308 */
309 buf->mem->mem_flags |= NVGPU_MEM_FLAG_USER_MEM;
310
311 return buf;
312
313fail:
314 /* buf will never be NULL here. */
315 nvgpu_kfree(g, buf->mem);
316 nvgpu_kfree(g, buf);
317 return NULL;
318}
319
320void nvgpu_vidmem_buf_free(struct gk20a *g, struct nvgpu_vidmem_buf *buf)
321{
322 /*
323 * In some error paths it's convenient to be able to "free" a NULL buf.
324 */
325 if (!buf)
326 return;
327
328 nvgpu_dma_free(g, buf->mem);
329
330 /*
331 * We don't free buf->mem here. This is handled by nvgpu_dma_free()!
332 * Since these buffers are cleared in the background the nvgpu_mem
333 * struct must live on through that. We transfer ownership here to the
334 * DMA API and let the DMA API free the buffer.
335 */
336 nvgpu_kfree(g, buf);
337}