diff options
author | Alex Waterman <alexw@nvidia.com> | 2017-09-13 16:49:49 -0400 |
---|---|---|
committer | mobile promotions <svcmobile_promotions@nvidia.com> | 2017-09-20 00:50:18 -0400 |
commit | 3821811214d80647abc1d65f1cff4201c65d63e1 (patch) | |
tree | 1619ec7ff6d765abfb847490ac4ffd0da6a6ebf9 /drivers/gpu/nvgpu/common | |
parent | 1132fd2a12a48271f94e995c0466c48b8228c185 (diff) |
gpu: nvgpu: Add DMA logging
Add logging prints for the DMA interface in nvgpu. These prints show
size, aligned size, type of alloc (sysmem vs vidmem), and flags for
the alloc.
Bug 1956137
Change-Id: I3e15152959dbb256cb1679435a18ab6821f4cde3
Signed-off-by: Alex Waterman <alexw@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/1559376
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/common')
-rw-r--r-- | drivers/gpu/nvgpu/common/linux/dma.c | 114 |
1 files changed, 110 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 | ||