aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian König <christian.koenig@amd.com>2017-08-07 11:46:49 -0400
committerAlex Deucher <alexander.deucher@amd.com>2017-08-17 15:46:03 -0400
commit3c848bb38aca1f7fd23edeb867b89d714a2e6ce2 (patch)
tree37886a411c494568d6ba4c82176ca327680b520b
parent9255d77d8cfd714f336a48168a9dada32912b19a (diff)
drm/amdgpu: move vram usage tracking into the vram manager v2
Looks like a better place for this. v2: use atomic64_t members instead Signed-off-by: Christian König <christian.koenig@amd.com> Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu.h2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c5
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c9
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_object.c50
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h3
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c72
6 files changed, 79 insertions, 62 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 593618e6c186..ad944aea0d4b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -1482,8 +1482,6 @@ struct amdgpu_device {
1482 struct amdgpu_mman mman; 1482 struct amdgpu_mman mman;
1483 struct amdgpu_vram_scratch vram_scratch; 1483 struct amdgpu_vram_scratch vram_scratch;
1484 struct amdgpu_wb wb; 1484 struct amdgpu_wb wb;
1485 atomic64_t vram_usage;
1486 atomic64_t vram_vis_usage;
1487 atomic64_t num_bytes_moved; 1485 atomic64_t num_bytes_moved;
1488 atomic64_t num_evictions; 1486 atomic64_t num_evictions;
1489 atomic64_t num_vram_cpu_page_faults; 1487 atomic64_t num_vram_cpu_page_faults;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index 825784b3b193..7e71a511990e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -246,7 +246,7 @@ static void amdgpu_cs_get_threshold_for_moves(struct amdgpu_device *adev,
246 } 246 }
247 247
248 total_vram = adev->mc.real_vram_size - adev->vram_pin_size; 248 total_vram = adev->mc.real_vram_size - adev->vram_pin_size;
249 used_vram = atomic64_read(&adev->vram_usage); 249 used_vram = amdgpu_vram_mgr_usage(&adev->mman.bdev.man[TTM_PL_VRAM]);
250 free_vram = used_vram >= total_vram ? 0 : total_vram - used_vram; 250 free_vram = used_vram >= total_vram ? 0 : total_vram - used_vram;
251 251
252 spin_lock(&adev->mm_stats.lock); 252 spin_lock(&adev->mm_stats.lock);
@@ -292,7 +292,8 @@ static void amdgpu_cs_get_threshold_for_moves(struct amdgpu_device *adev,
292 /* Do the same for visible VRAM if half of it is free */ 292 /* Do the same for visible VRAM if half of it is free */
293 if (adev->mc.visible_vram_size < adev->mc.real_vram_size) { 293 if (adev->mc.visible_vram_size < adev->mc.real_vram_size) {
294 u64 total_vis_vram = adev->mc.visible_vram_size; 294 u64 total_vis_vram = adev->mc.visible_vram_size;
295 u64 used_vis_vram = atomic64_read(&adev->vram_vis_usage); 295 u64 used_vis_vram =
296 amdgpu_vram_mgr_vis_usage(&adev->mman.bdev.man[TTM_PL_VRAM]);
296 297
297 if (used_vis_vram < total_vis_vram) { 298 if (used_vis_vram < total_vis_vram) {
298 u64 free_vis_vram = total_vis_vram - used_vis_vram; 299 u64 free_vis_vram = total_vis_vram - used_vis_vram;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
index 889f96fcfc81..29cd5dabf8b5 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
@@ -455,10 +455,10 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
455 ui64 = atomic64_read(&adev->num_vram_cpu_page_faults); 455 ui64 = atomic64_read(&adev->num_vram_cpu_page_faults);
456 return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0; 456 return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0;
457 case AMDGPU_INFO_VRAM_USAGE: 457 case AMDGPU_INFO_VRAM_USAGE:
458 ui64 = atomic64_read(&adev->vram_usage); 458 ui64 = amdgpu_vram_mgr_usage(&adev->mman.bdev.man[TTM_PL_VRAM]);
459 return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0; 459 return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0;
460 case AMDGPU_INFO_VIS_VRAM_USAGE: 460 case AMDGPU_INFO_VIS_VRAM_USAGE:
461 ui64 = atomic64_read(&adev->vram_vis_usage); 461 ui64 = amdgpu_vram_mgr_vis_usage(&adev->mman.bdev.man[TTM_PL_VRAM]);
462 return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0; 462 return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0;
463 case AMDGPU_INFO_GTT_USAGE: 463 case AMDGPU_INFO_GTT_USAGE:
464 ui64 = amdgpu_gtt_mgr_usage(&adev->mman.bdev.man[TTM_PL_TT]); 464 ui64 = amdgpu_gtt_mgr_usage(&adev->mman.bdev.man[TTM_PL_TT]);
@@ -497,7 +497,8 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
497 mem.vram.total_heap_size = adev->mc.real_vram_size; 497 mem.vram.total_heap_size = adev->mc.real_vram_size;
498 mem.vram.usable_heap_size = 498 mem.vram.usable_heap_size =
499 adev->mc.real_vram_size - adev->vram_pin_size; 499 adev->mc.real_vram_size - adev->vram_pin_size;
500 mem.vram.heap_usage = atomic64_read(&adev->vram_usage); 500 mem.vram.heap_usage =
501 amdgpu_vram_mgr_usage(&adev->mman.bdev.man[TTM_PL_VRAM]);
501 mem.vram.max_allocation = mem.vram.usable_heap_size * 3 / 4; 502 mem.vram.max_allocation = mem.vram.usable_heap_size * 3 / 4;
502 503
503 mem.cpu_accessible_vram.total_heap_size = 504 mem.cpu_accessible_vram.total_heap_size =
@@ -506,7 +507,7 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
506 adev->mc.visible_vram_size - 507 adev->mc.visible_vram_size -
507 (adev->vram_pin_size - adev->invisible_pin_size); 508 (adev->vram_pin_size - adev->invisible_pin_size);
508 mem.cpu_accessible_vram.heap_usage = 509 mem.cpu_accessible_vram.heap_usage =
509 atomic64_read(&adev->vram_vis_usage); 510 amdgpu_vram_mgr_vis_usage(&adev->mman.bdev.man[TTM_PL_VRAM]);
510 mem.cpu_accessible_vram.max_allocation = 511 mem.cpu_accessible_vram.max_allocation =
511 mem.cpu_accessible_vram.usable_heap_size * 3 / 4; 512 mem.cpu_accessible_vram.usable_heap_size * 3 / 4;
512 513
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
index 57d2cb6bd331..e7e899190bef 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
@@ -37,53 +37,6 @@
37#include "amdgpu.h" 37#include "amdgpu.h"
38#include "amdgpu_trace.h" 38#include "amdgpu_trace.h"
39 39
40
41
42static u64 amdgpu_get_vis_part_size(struct amdgpu_device *adev,
43 struct ttm_mem_reg *mem)
44{
45 if (mem->start << PAGE_SHIFT >= adev->mc.visible_vram_size)
46 return 0;
47
48 return ((mem->start << PAGE_SHIFT) + mem->size) >
49 adev->mc.visible_vram_size ?
50 adev->mc.visible_vram_size - (mem->start << PAGE_SHIFT) :
51 mem->size;
52}
53
54static void amdgpu_update_memory_usage(struct amdgpu_device *adev,
55 struct ttm_mem_reg *old_mem,
56 struct ttm_mem_reg *new_mem)
57{
58 u64 vis_size;
59 if (!adev)
60 return;
61
62 if (new_mem) {
63 switch (new_mem->mem_type) {
64 case TTM_PL_TT:
65 break;
66 case TTM_PL_VRAM:
67 atomic64_add(new_mem->size, &adev->vram_usage);
68 vis_size = amdgpu_get_vis_part_size(adev, new_mem);
69 atomic64_add(vis_size, &adev->vram_vis_usage);
70 break;
71 }
72 }
73
74 if (old_mem) {
75 switch (old_mem->mem_type) {
76 case TTM_PL_TT:
77 break;
78 case TTM_PL_VRAM:
79 atomic64_sub(old_mem->size, &adev->vram_usage);
80 vis_size = amdgpu_get_vis_part_size(adev, old_mem);
81 atomic64_sub(vis_size, &adev->vram_vis_usage);
82 break;
83 }
84 }
85}
86
87static void amdgpu_ttm_bo_destroy(struct ttm_buffer_object *tbo) 40static void amdgpu_ttm_bo_destroy(struct ttm_buffer_object *tbo)
88{ 41{
89 struct amdgpu_device *adev = amdgpu_ttm_adev(tbo->bdev); 42 struct amdgpu_device *adev = amdgpu_ttm_adev(tbo->bdev);
@@ -92,7 +45,6 @@ static void amdgpu_ttm_bo_destroy(struct ttm_buffer_object *tbo)
92 bo = container_of(tbo, struct amdgpu_bo, tbo); 45 bo = container_of(tbo, struct amdgpu_bo, tbo);
93 46
94 amdgpu_bo_kunmap(bo); 47 amdgpu_bo_kunmap(bo);
95 amdgpu_update_memory_usage(adev, &bo->tbo.mem, NULL);
96 48
97 drm_gem_object_release(&bo->gem_base); 49 drm_gem_object_release(&bo->gem_base);
98 amdgpu_bo_unref(&bo->parent); 50 amdgpu_bo_unref(&bo->parent);
@@ -990,8 +942,6 @@ void amdgpu_bo_move_notify(struct ttm_buffer_object *bo,
990 return; 942 return;
991 943
992 /* move_notify is called before move happens */ 944 /* move_notify is called before move happens */
993 amdgpu_update_memory_usage(adev, &bo->mem, new_mem);
994
995 trace_amdgpu_ttm_bo_move(abo, new_mem->mem_type, old_mem->mem_type); 945 trace_amdgpu_ttm_bo_move(abo, new_mem->mem_type, old_mem->mem_type);
996} 946}
997 947
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
index 1307ab581449..f22a4758719d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
@@ -68,6 +68,9 @@ int amdgpu_gtt_mgr_alloc(struct ttm_mem_type_manager *man,
68 struct ttm_mem_reg *mem); 68 struct ttm_mem_reg *mem);
69uint64_t amdgpu_gtt_mgr_usage(struct ttm_mem_type_manager *man); 69uint64_t amdgpu_gtt_mgr_usage(struct ttm_mem_type_manager *man);
70 70
71uint64_t amdgpu_vram_mgr_usage(struct ttm_mem_type_manager *man);
72uint64_t amdgpu_vram_mgr_vis_usage(struct ttm_mem_type_manager *man);
73
71int amdgpu_copy_buffer(struct amdgpu_ring *ring, uint64_t src_offset, 74int amdgpu_copy_buffer(struct amdgpu_ring *ring, uint64_t src_offset,
72 uint64_t dst_offset, uint32_t byte_count, 75 uint64_t dst_offset, uint32_t byte_count,
73 struct reservation_object *resv, 76 struct reservation_object *resv,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
index 1eb8d5d3acf2..26e900627971 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
@@ -28,6 +28,8 @@
28struct amdgpu_vram_mgr { 28struct amdgpu_vram_mgr {
29 struct drm_mm mm; 29 struct drm_mm mm;
30 spinlock_t lock; 30 spinlock_t lock;
31 atomic64_t usage;
32 atomic64_t vis_usage;
31}; 33};
32 34
33/** 35/**
@@ -79,6 +81,27 @@ static int amdgpu_vram_mgr_fini(struct ttm_mem_type_manager *man)
79} 81}
80 82
81/** 83/**
84 * amdgpu_vram_mgr_vis_size - Calculate visible node size
85 *
86 * @adev: amdgpu device structure
87 * @node: MM node structure
88 *
89 * Calculate how many bytes of the MM node are inside visible VRAM
90 */
91static u64 amdgpu_vram_mgr_vis_size(struct amdgpu_device *adev,
92 struct drm_mm_node *node)
93{
94 uint64_t start = node->start << PAGE_SHIFT;
95 uint64_t end = (node->size + node->start) << PAGE_SHIFT;
96
97 if (start >= adev->mc.visible_vram_size)
98 return 0;
99
100 return (end > adev->mc.visible_vram_size ?
101 adev->mc.visible_vram_size : end) - start;
102}
103
104/**
82 * amdgpu_vram_mgr_new - allocate new ranges 105 * amdgpu_vram_mgr_new - allocate new ranges
83 * 106 *
84 * @man: TTM memory type manager 107 * @man: TTM memory type manager
@@ -93,11 +116,13 @@ static int amdgpu_vram_mgr_new(struct ttm_mem_type_manager *man,
93 const struct ttm_place *place, 116 const struct ttm_place *place,
94 struct ttm_mem_reg *mem) 117 struct ttm_mem_reg *mem)
95{ 118{
119 struct amdgpu_device *adev = amdgpu_ttm_adev(man->bdev);
96 struct amdgpu_vram_mgr *mgr = man->priv; 120 struct amdgpu_vram_mgr *mgr = man->priv;
97 struct drm_mm *mm = &mgr->mm; 121 struct drm_mm *mm = &mgr->mm;
98 struct drm_mm_node *nodes; 122 struct drm_mm_node *nodes;
99 enum drm_mm_insert_mode mode; 123 enum drm_mm_insert_mode mode;
100 unsigned long lpfn, num_nodes, pages_per_node, pages_left; 124 unsigned long lpfn, num_nodes, pages_per_node, pages_left;
125 uint64_t usage = 0, vis_usage = 0;
101 unsigned i; 126 unsigned i;
102 int r; 127 int r;
103 128
@@ -142,6 +167,9 @@ static int amdgpu_vram_mgr_new(struct ttm_mem_type_manager *man,
142 if (unlikely(r)) 167 if (unlikely(r))
143 goto error; 168 goto error;
144 169
170 usage += nodes[i].size << PAGE_SHIFT;
171 vis_usage += amdgpu_vram_mgr_vis_size(adev, &nodes[i]);
172
145 /* Calculate a virtual BO start address to easily check if 173 /* Calculate a virtual BO start address to easily check if
146 * everything is CPU accessible. 174 * everything is CPU accessible.
147 */ 175 */
@@ -155,6 +183,9 @@ static int amdgpu_vram_mgr_new(struct ttm_mem_type_manager *man,
155 } 183 }
156 spin_unlock(&mgr->lock); 184 spin_unlock(&mgr->lock);
157 185
186 atomic64_add(usage, &mgr->usage);
187 atomic64_add(vis_usage, &mgr->vis_usage);
188
158 mem->mm_node = nodes; 189 mem->mm_node = nodes;
159 190
160 return 0; 191 return 0;
@@ -181,8 +212,10 @@ error:
181static void amdgpu_vram_mgr_del(struct ttm_mem_type_manager *man, 212static void amdgpu_vram_mgr_del(struct ttm_mem_type_manager *man,
182 struct ttm_mem_reg *mem) 213 struct ttm_mem_reg *mem)
183{ 214{
215 struct amdgpu_device *adev = amdgpu_ttm_adev(man->bdev);
184 struct amdgpu_vram_mgr *mgr = man->priv; 216 struct amdgpu_vram_mgr *mgr = man->priv;
185 struct drm_mm_node *nodes = mem->mm_node; 217 struct drm_mm_node *nodes = mem->mm_node;
218 uint64_t usage = 0, vis_usage = 0;
186 unsigned pages = mem->num_pages; 219 unsigned pages = mem->num_pages;
187 220
188 if (!mem->mm_node) 221 if (!mem->mm_node)
@@ -192,15 +225,48 @@ static void amdgpu_vram_mgr_del(struct ttm_mem_type_manager *man,
192 while (pages) { 225 while (pages) {
193 pages -= nodes->size; 226 pages -= nodes->size;
194 drm_mm_remove_node(nodes); 227 drm_mm_remove_node(nodes);
228 usage += nodes->size << PAGE_SHIFT;
229 vis_usage += amdgpu_vram_mgr_vis_size(adev, nodes);
195 ++nodes; 230 ++nodes;
196 } 231 }
197 spin_unlock(&mgr->lock); 232 spin_unlock(&mgr->lock);
198 233
234 atomic64_sub(usage, &mgr->usage);
235 atomic64_sub(vis_usage, &mgr->vis_usage);
236
199 kfree(mem->mm_node); 237 kfree(mem->mm_node);
200 mem->mm_node = NULL; 238 mem->mm_node = NULL;
201} 239}
202 240
203/** 241/**
242 * amdgpu_vram_mgr_usage - how many bytes are used in this domain
243 *
244 * @man: TTM memory type manager
245 *
246 * Returns how many bytes are used in this domain.
247 */
248uint64_t amdgpu_vram_mgr_usage(struct ttm_mem_type_manager *man)
249{
250 struct amdgpu_vram_mgr *mgr = man->priv;
251
252 return atomic64_read(&mgr->usage);
253}
254
255/**
256 * amdgpu_vram_mgr_vis_usage - how many bytes are used in the visible part
257 *
258 * @man: TTM memory type manager
259 *
260 * Returns how many bytes are used in the visible part of VRAM
261 */
262uint64_t amdgpu_vram_mgr_vis_usage(struct ttm_mem_type_manager *man)
263{
264 struct amdgpu_vram_mgr *mgr = man->priv;
265
266 return atomic64_read(&mgr->vis_usage);
267}
268
269/**
204 * amdgpu_vram_mgr_debug - dump VRAM table 270 * amdgpu_vram_mgr_debug - dump VRAM table
205 * 271 *
206 * @man: TTM memory type manager 272 * @man: TTM memory type manager
@@ -211,7 +277,6 @@ static void amdgpu_vram_mgr_del(struct ttm_mem_type_manager *man,
211static void amdgpu_vram_mgr_debug(struct ttm_mem_type_manager *man, 277static void amdgpu_vram_mgr_debug(struct ttm_mem_type_manager *man,
212 struct drm_printer *printer) 278 struct drm_printer *printer)
213{ 279{
214 struct amdgpu_device *adev = amdgpu_ttm_adev(man->bdev);
215 struct amdgpu_vram_mgr *mgr = man->priv; 280 struct amdgpu_vram_mgr *mgr = man->priv;
216 281
217 spin_lock(&mgr->lock); 282 spin_lock(&mgr->lock);
@@ -219,9 +284,8 @@ static void amdgpu_vram_mgr_debug(struct ttm_mem_type_manager *man,
219 spin_unlock(&mgr->lock); 284 spin_unlock(&mgr->lock);
220 285
221 drm_printf(printer, "man size:%llu pages, ram usage:%lluMB, vis usage:%lluMB\n", 286 drm_printf(printer, "man size:%llu pages, ram usage:%lluMB, vis usage:%lluMB\n",
222 adev->mman.bdev.man[TTM_PL_VRAM].size, 287 man->size, amdgpu_vram_mgr_usage(man) >> 20,
223 (u64)atomic64_read(&adev->vram_usage) >> 20, 288 amdgpu_vram_mgr_vis_usage(man) >> 20);
224 (u64)atomic64_read(&adev->vram_vis_usage) >> 20);
225} 289}
226 290
227const struct ttm_mem_type_manager_func amdgpu_vram_mgr_func = { 291const struct ttm_mem_type_manager_func amdgpu_vram_mgr_func = {