diff options
author | Tom St Denis <tom.stdenis@amd.com> | 2019-06-10 09:53:58 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2019-06-13 14:59:48 -0400 |
commit | c5e4c6bbbdce750a52ae65c429384e7324a50fd3 (patch) | |
tree | 5d6123812e96408941049b5b865a7ee3e0c24ec3 /drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c | |
parent | e9bc1bf7916e006f62a27f400f74a6e10b874886 (diff) |
drm/amd/amdgpu: Bail out of BO node creation if not enough VRAM (v3)
(v2): Return 0 and set mem->mm_node to NULL.
(v3): Use atomic64_add_return instead.
Signed-off-by: Tom St Denis <tom.stdenis@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c index 8aea2f21b202..c963ad86072e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c | |||
@@ -276,7 +276,7 @@ static int amdgpu_vram_mgr_new(struct ttm_mem_type_manager *man, | |||
276 | struct drm_mm_node *nodes; | 276 | struct drm_mm_node *nodes; |
277 | enum drm_mm_insert_mode mode; | 277 | enum drm_mm_insert_mode mode; |
278 | unsigned long lpfn, num_nodes, pages_per_node, pages_left; | 278 | unsigned long lpfn, num_nodes, pages_per_node, pages_left; |
279 | uint64_t usage = 0, vis_usage = 0; | 279 | uint64_t vis_usage = 0; |
280 | unsigned i; | 280 | unsigned i; |
281 | int r; | 281 | int r; |
282 | 282 | ||
@@ -284,6 +284,13 @@ static int amdgpu_vram_mgr_new(struct ttm_mem_type_manager *man, | |||
284 | if (!lpfn) | 284 | if (!lpfn) |
285 | lpfn = man->size; | 285 | lpfn = man->size; |
286 | 286 | ||
287 | /* bail out quickly if there's likely not enough VRAM for this BO */ | ||
288 | if (atomic64_add_return(mem->num_pages << PAGE_SHIFT, &mgr->usage) > adev->gmc.mc_vram_size) { | ||
289 | atomic64_sub(mem->num_pages << PAGE_SHIFT, &mgr->usage); | ||
290 | mem->mm_node = NULL; | ||
291 | return 0; | ||
292 | } | ||
293 | |||
287 | if (place->flags & TTM_PL_FLAG_CONTIGUOUS) { | 294 | if (place->flags & TTM_PL_FLAG_CONTIGUOUS) { |
288 | pages_per_node = ~0ul; | 295 | pages_per_node = ~0ul; |
289 | num_nodes = 1; | 296 | num_nodes = 1; |
@@ -300,8 +307,10 @@ static int amdgpu_vram_mgr_new(struct ttm_mem_type_manager *man, | |||
300 | 307 | ||
301 | nodes = kvmalloc_array((uint32_t)num_nodes, sizeof(*nodes), | 308 | nodes = kvmalloc_array((uint32_t)num_nodes, sizeof(*nodes), |
302 | GFP_KERNEL | __GFP_ZERO); | 309 | GFP_KERNEL | __GFP_ZERO); |
303 | if (!nodes) | 310 | if (!nodes) { |
311 | atomic64_sub(mem->num_pages << PAGE_SHIFT, &mgr->usage); | ||
304 | return -ENOMEM; | 312 | return -ENOMEM; |
313 | } | ||
305 | 314 | ||
306 | mode = DRM_MM_INSERT_BEST; | 315 | mode = DRM_MM_INSERT_BEST; |
307 | if (place->flags & TTM_PL_FLAG_TOPDOWN) | 316 | if (place->flags & TTM_PL_FLAG_TOPDOWN) |
@@ -321,7 +330,6 @@ static int amdgpu_vram_mgr_new(struct ttm_mem_type_manager *man, | |||
321 | if (unlikely(r)) | 330 | if (unlikely(r)) |
322 | break; | 331 | break; |
323 | 332 | ||
324 | usage += nodes[i].size << PAGE_SHIFT; | ||
325 | vis_usage += amdgpu_vram_mgr_vis_size(adev, &nodes[i]); | 333 | vis_usage += amdgpu_vram_mgr_vis_size(adev, &nodes[i]); |
326 | amdgpu_vram_mgr_virt_start(mem, &nodes[i]); | 334 | amdgpu_vram_mgr_virt_start(mem, &nodes[i]); |
327 | pages_left -= pages; | 335 | pages_left -= pages; |
@@ -341,14 +349,12 @@ static int amdgpu_vram_mgr_new(struct ttm_mem_type_manager *man, | |||
341 | if (unlikely(r)) | 349 | if (unlikely(r)) |
342 | goto error; | 350 | goto error; |
343 | 351 | ||
344 | usage += nodes[i].size << PAGE_SHIFT; | ||
345 | vis_usage += amdgpu_vram_mgr_vis_size(adev, &nodes[i]); | 352 | vis_usage += amdgpu_vram_mgr_vis_size(adev, &nodes[i]); |
346 | amdgpu_vram_mgr_virt_start(mem, &nodes[i]); | 353 | amdgpu_vram_mgr_virt_start(mem, &nodes[i]); |
347 | pages_left -= pages; | 354 | pages_left -= pages; |
348 | } | 355 | } |
349 | spin_unlock(&mgr->lock); | 356 | spin_unlock(&mgr->lock); |
350 | 357 | ||
351 | atomic64_add(usage, &mgr->usage); | ||
352 | atomic64_add(vis_usage, &mgr->vis_usage); | 358 | atomic64_add(vis_usage, &mgr->vis_usage); |
353 | 359 | ||
354 | mem->mm_node = nodes; | 360 | mem->mm_node = nodes; |
@@ -359,6 +365,7 @@ error: | |||
359 | while (i--) | 365 | while (i--) |
360 | drm_mm_remove_node(&nodes[i]); | 366 | drm_mm_remove_node(&nodes[i]); |
361 | spin_unlock(&mgr->lock); | 367 | spin_unlock(&mgr->lock); |
368 | atomic64_sub(mem->num_pages << PAGE_SHIFT, &mgr->usage); | ||
362 | 369 | ||
363 | kvfree(nodes); | 370 | kvfree(nodes); |
364 | return r == -ENOSPC ? 0 : r; | 371 | return r == -ENOSPC ? 0 : r; |