diff options
Diffstat (limited to 'drivers/gpu/nvgpu')
-rw-r--r-- | drivers/gpu/nvgpu/common/linux/dma.c | 114 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/include/nvgpu/log.h | 1 |
2 files changed, 111 insertions, 4 deletions
diff --git a/drivers/gpu/nvgpu/common/linux/dma.c b/drivers/gpu/nvgpu/common/linux/dma.c index 43009fca..eff60f5b 100644 --- a/drivers/gpu/nvgpu/common/linux/dma.c +++ b/drivers/gpu/nvgpu/common/linux/dma.c | |||
@@ -18,10 +18,12 @@ | |||
18 | #include <linux/dma-mapping.h> | 18 | #include <linux/dma-mapping.h> |
19 | #include <linux/version.h> | 19 | #include <linux/version.h> |
20 | 20 | ||
21 | #include <nvgpu/log.h> | ||
21 | #include <nvgpu/dma.h> | 22 | #include <nvgpu/dma.h> |
22 | #include <nvgpu/lock.h> | 23 | #include <nvgpu/lock.h> |
23 | #include <nvgpu/bug.h> | 24 | #include <nvgpu/bug.h> |
24 | #include <nvgpu/gmmu.h> | 25 | #include <nvgpu/gmmu.h> |
26 | #include <nvgpu/kmem.h> | ||
25 | #include <nvgpu/enabled.h> | 27 | #include <nvgpu/enabled.h> |
26 | 28 | ||
27 | #include <nvgpu/linux/dma.h> | 29 | #include <nvgpu/linux/dma.h> |
@@ -30,6 +32,101 @@ | |||
30 | #include "gk20a/platform_gk20a.h" | 32 | #include "gk20a/platform_gk20a.h" |
31 | #include "os_linux.h" | 33 | #include "os_linux.h" |
32 | 34 | ||
35 | /* | ||
36 | * Enough to hold all the possible flags in string form. When a new flag is | ||
37 | * added it must be added here as well!! | ||
38 | */ | ||
39 | #define NVGPU_DMA_STR_SIZE \ | ||
40 | sizeof("NO_KERNEL_MAPPING FORCE_CONTIGUOUS READ_ONLY") | ||
41 | |||
42 | /* | ||
43 | * The returned string is kmalloc()ed here but must be freed by the caller. | ||
44 | */ | ||
45 | static char *nvgpu_dma_flags_to_str(struct gk20a *g, unsigned long flags) | ||
46 | { | ||
47 | char *buf = nvgpu_kzalloc(g, NVGPU_DMA_STR_SIZE); | ||
48 | int bytes_available = NVGPU_DMA_STR_SIZE; | ||
49 | |||
50 | /* | ||
51 | * Return the empty buffer if there's no flags. Makes it easier on the | ||
52 | * calling code to just print it instead of any if (NULL) type logic. | ||
53 | */ | ||
54 | if (!flags) | ||
55 | return buf; | ||
56 | |||
57 | #define APPEND_FLAG(flag, str_flag) \ | ||
58 | do { \ | ||
59 | if (flags & flag) { \ | ||
60 | strncat(buf, str_flag, bytes_available); \ | ||
61 | bytes_available -= strlen(str_flag); \ | ||
62 | } \ | ||
63 | } while (0) | ||
64 | |||
65 | APPEND_FLAG(NVGPU_DMA_NO_KERNEL_MAPPING, "NO_KERNEL_MAPPING "); | ||
66 | APPEND_FLAG(NVGPU_DMA_FORCE_CONTIGUOUS, "FORCE_CONTIGUOUS "); | ||
67 | APPEND_FLAG(NVGPU_DMA_READ_ONLY, "READ_ONLY"); | ||
68 | #undef APPEND_FLAG | ||
69 | |||
70 | return buf; | ||
71 | } | ||
72 | |||
73 | /** | ||
74 | * __dma_dbg - Debug print for DMA allocs and frees. | ||
75 | * | ||
76 | * @g - The GPU. | ||
77 | * @size - The requested size of the alloc (size_t). | ||
78 | * @flags - The flags (unsigned long). | ||
79 | * @type - A string describing the type (i.e: sysmem or vidmem). | ||
80 | * @what - A string with 'alloc' or 'free'. | ||
81 | * | ||
82 | * @flags is the DMA flags. If there are none or it doesn't make sense to print | ||
83 | * flags just pass 0. | ||
84 | * | ||
85 | * Please use dma_dbg_alloc() and dma_dbg_free() instead of this function. | ||
86 | */ | ||
87 | static void __dma_dbg(struct gk20a *g, size_t size, unsigned long flags, | ||
88 | const char *type, const char *what) | ||
89 | { | ||
90 | char *flags_str = NULL; | ||
91 | |||
92 | /* | ||
93 | * Don't bother making the flags_str if debugging is | ||
94 | * not enabled. This saves a malloc and a free. | ||
95 | */ | ||
96 | if (!nvgpu_log_mask_enabled(g, gpu_dbg_dma)) | ||
97 | return; | ||
98 | |||
99 | flags_str = nvgpu_dma_flags_to_str(g, flags); | ||
100 | |||
101 | __nvgpu_log_dbg(g, gpu_dbg_dma, | ||
102 | __func__, __LINE__, | ||
103 | "DMA %s: [%s] size=%-7zu aligned=%-7zu %s", | ||
104 | what, type, | ||
105 | size, PAGE_ALIGN(size), | ||
106 | flags_str); | ||
107 | |||
108 | if (flags_str) | ||
109 | nvgpu_kfree(g, flags_str); | ||
110 | } | ||
111 | |||
112 | #define dma_dbg_alloc(g, size, flags, type) \ | ||
113 | __dma_dbg(g, size, flags, type, "alloc") | ||
114 | #define dma_dbg_free(g, size, flags, type) \ | ||
115 | __dma_dbg(g, size, flags, type, "free") | ||
116 | |||
117 | /* | ||
118 | * For after the DMA alloc is done. | ||
119 | */ | ||
120 | #define __dma_dbg_done(g, size, type, what) \ | ||
121 | nvgpu_log(g, gpu_dbg_dma, \ | ||
122 | "DMA %s: [%s] size=%-7zu Done!", \ | ||
123 | what, type, size); \ | ||
124 | |||
125 | #define dma_dbg_alloc_done(g, size, type) \ | ||
126 | __dma_dbg_done(g, size, type, "alloc") | ||
127 | #define dma_dbg_free_done(g, size, type) \ | ||
128 | __dma_dbg_done(g, size, type, "free") | ||
129 | |||
33 | #if defined(CONFIG_GK20A_VIDMEM) | 130 | #if defined(CONFIG_GK20A_VIDMEM) |
34 | static u64 __nvgpu_dma_alloc(struct nvgpu_allocator *allocator, dma_addr_t at, | 131 | static u64 __nvgpu_dma_alloc(struct nvgpu_allocator *allocator, dma_addr_t at, |
35 | size_t size) | 132 | size_t size) |
@@ -110,7 +207,7 @@ int nvgpu_dma_alloc_flags_sys(struct gk20a *g, unsigned long flags, | |||
110 | int err; | 207 | int err; |
111 | dma_addr_t iova; | 208 | dma_addr_t iova; |
112 | 209 | ||
113 | gk20a_dbg_fn(""); | 210 | dma_dbg_alloc(g, size, flags, "sysmem"); |
114 | 211 | ||
115 | /* | 212 | /* |
116 | * Save the old size but for actual allocation purposes the size is | 213 | * Save the old size but for actual allocation purposes the size is |
@@ -159,7 +256,7 @@ int nvgpu_dma_alloc_flags_sys(struct gk20a *g, unsigned long flags, | |||
159 | mem->aperture = APERTURE_SYSMEM; | 256 | mem->aperture = APERTURE_SYSMEM; |
160 | mem->priv.flags = flags; | 257 | mem->priv.flags = flags; |
161 | 258 | ||
162 | gk20a_dbg_fn("done"); | 259 | dma_dbg_alloc_done(g, mem->size, "sysmem"); |
163 | 260 | ||
164 | return 0; | 261 | return 0; |
165 | 262 | ||
@@ -194,7 +291,7 @@ int nvgpu_dma_alloc_flags_vid_at(struct gk20a *g, unsigned long flags, | |||
194 | &g->mm.vidmem.bootstrap_allocator; | 291 | &g->mm.vidmem.bootstrap_allocator; |
195 | int before_pending; | 292 | int before_pending; |
196 | 293 | ||
197 | gk20a_dbg_fn(""); | 294 | dma_dbg_alloc(g, size, flags, "vidmem"); |
198 | 295 | ||
199 | mem->size = size; | 296 | mem->size = size; |
200 | size = PAGE_ALIGN(size); | 297 | size = PAGE_ALIGN(size); |
@@ -246,7 +343,7 @@ int nvgpu_dma_alloc_flags_vid_at(struct gk20a *g, unsigned long flags, | |||
246 | 343 | ||
247 | nvgpu_init_list_node(&mem->clear_list_entry); | 344 | nvgpu_init_list_node(&mem->clear_list_entry); |
248 | 345 | ||
249 | gk20a_dbg_fn("done at 0x%llx size %zu", addr, size); | 346 | dma_dbg_alloc_done(g, mem->size, "vidmem"); |
250 | 347 | ||
251 | return 0; | 348 | return 0; |
252 | 349 | ||
@@ -355,6 +452,8 @@ static void nvgpu_dma_free_sys(struct gk20a *g, struct nvgpu_mem *mem) | |||
355 | { | 452 | { |
356 | struct device *d = dev_from_gk20a(g); | 453 | struct device *d = dev_from_gk20a(g); |
357 | 454 | ||
455 | dma_dbg_free(g, mem->size, mem->priv.flags, "sysmem"); | ||
456 | |||
358 | if (!(mem->mem_flags & NVGPU_MEM_FLAG_SHADOW_COPY) && | 457 | if (!(mem->mem_flags & NVGPU_MEM_FLAG_SHADOW_COPY) && |
359 | !(mem->mem_flags & __NVGPU_MEM_FLAG_NO_DMA) && | 458 | !(mem->mem_flags & __NVGPU_MEM_FLAG_NO_DMA) && |
360 | (mem->cpu_va || mem->priv.pages)) { | 459 | (mem->cpu_va || mem->priv.pages)) { |
@@ -390,6 +489,8 @@ static void nvgpu_dma_free_sys(struct gk20a *g, struct nvgpu_mem *mem) | |||
390 | if (mem->priv.sgt) | 489 | if (mem->priv.sgt) |
391 | nvgpu_free_sgtable(g, &mem->priv.sgt); | 490 | nvgpu_free_sgtable(g, &mem->priv.sgt); |
392 | 491 | ||
492 | dma_dbg_free_done(g, mem->size, "sysmem"); | ||
493 | |||
393 | mem->size = 0; | 494 | mem->size = 0; |
394 | mem->aligned_size = 0; | 495 | mem->aligned_size = 0; |
395 | mem->aperture = APERTURE_INVALID; | 496 | mem->aperture = APERTURE_INVALID; |
@@ -399,6 +500,9 @@ static void nvgpu_dma_free_vid(struct gk20a *g, struct nvgpu_mem *mem) | |||
399 | { | 500 | { |
400 | #if defined(CONFIG_GK20A_VIDMEM) | 501 | #if defined(CONFIG_GK20A_VIDMEM) |
401 | bool was_empty; | 502 | bool was_empty; |
503 | size_t mem_size = mem->size; | ||
504 | |||
505 | dma_dbg_free(g, mem->size, mem->priv.flags, "vidmem"); | ||
402 | 506 | ||
403 | /* Sanity check - only this supported when allocating. */ | 507 | /* Sanity check - only this supported when allocating. */ |
404 | WARN_ON(mem->priv.flags != NVGPU_DMA_NO_KERNEL_MAPPING); | 508 | WARN_ON(mem->priv.flags != NVGPU_DMA_NO_KERNEL_MAPPING); |
@@ -426,6 +530,8 @@ static void nvgpu_dma_free_vid(struct gk20a *g, struct nvgpu_mem *mem) | |||
426 | mem->aligned_size = 0; | 530 | mem->aligned_size = 0; |
427 | mem->aperture = APERTURE_INVALID; | 531 | mem->aperture = APERTURE_INVALID; |
428 | } | 532 | } |
533 | |||
534 | dma_dbg_free_done(g, mem_size, "vidmem"); | ||
429 | #endif | 535 | #endif |
430 | } | 536 | } |
431 | 537 | ||
diff --git a/drivers/gpu/nvgpu/include/nvgpu/log.h b/drivers/gpu/nvgpu/include/nvgpu/log.h index 11e6dacb..4cac3e70 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/log.h +++ b/drivers/gpu/nvgpu/include/nvgpu/log.h | |||
@@ -70,6 +70,7 @@ enum nvgpu_log_categories { | |||
70 | gpu_dbg_kmem = BIT(19), /* Kmem tracking debugging. */ | 70 | gpu_dbg_kmem = BIT(19), /* Kmem tracking debugging. */ |
71 | gpu_dbg_pd_cache = BIT(20), /* PD cache traces. */ | 71 | gpu_dbg_pd_cache = BIT(20), /* PD cache traces. */ |
72 | gpu_dbg_alloc = BIT(21), /* Allocator debugging. */ | 72 | gpu_dbg_alloc = BIT(21), /* Allocator debugging. */ |
73 | gpu_dbg_dma = BIT(22), /* DMA allocation prints. */ | ||
73 | gpu_dbg_mem = BIT(31), /* memory accesses; very verbose. */ | 74 | gpu_dbg_mem = BIT(31), /* memory accesses; very verbose. */ |
74 | }; | 75 | }; |
75 | 76 | ||