Skip to content

Commit e049fea

Browse files
ChristianKoenigAMDMa Wupeng
authored andcommitted
drm/amdgpu: fix visible VRAM handling during faults
stable inclusion from stable-v6.6.30 commit 4c5eaf0cad27a66c4788e0603b9f7a68df83a947 bugzilla: https://gitee.com/openeuler/kernel/issues/I9MPZ8 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=4c5eaf0cad27a66c4788e0603b9f7a68df83a947 -------------------------------- [ Upstream commit a6ff969fe9cbf369e3cd0ac54261fec1122682ec ] When we removed the hacky start code check we actually didn't took into account that *all* VRAM pages needs to be CPU accessible. Clean up the code and unify the handling into a single helper which checks if the whole resource is CPU accessible. The only place where a partial check would make sense is during eviction, but that is neglitible. Signed-off-by: Christian König <christian.koenig@amd.com> Fixes: aed01a6 ("drm/amdgpu: Remove TTM resource->start visible VRAM condition v2") Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com> CC: stable@vger.kernel.org Signed-off-by: Sasha Levin <sashal@kernel.org> Signed-off-by: ZhangPeng <zhangpeng362@huawei.com>
1 parent a63f8c5 commit e049fea

File tree

5 files changed

+53
-57
lines changed

5 files changed

+53
-57
lines changed

drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -819,7 +819,7 @@ static int amdgpu_cs_bo_validate(void *param, struct amdgpu_bo *bo)
819819

820820
p->bytes_moved += ctx.bytes_moved;
821821
if (!amdgpu_gmc_vram_full_visible(&adev->gmc) &&
822-
amdgpu_bo_in_cpu_visible_vram(bo))
822+
amdgpu_res_cpu_visible(adev, bo->tbo.resource))
823823
p->bytes_moved_vis += ctx.bytes_moved;
824824

825825
if (unlikely(r == -ENOMEM) && domain != bo->allowed_domains) {

drivers/gpu/drm/amd/amdgpu/amdgpu_object.c

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -625,8 +625,7 @@ int amdgpu_bo_create(struct amdgpu_device *adev,
625625
return r;
626626

627627
if (!amdgpu_gmc_vram_full_visible(&adev->gmc) &&
628-
bo->tbo.resource->mem_type == TTM_PL_VRAM &&
629-
amdgpu_bo_in_cpu_visible_vram(bo))
628+
amdgpu_res_cpu_visible(adev, bo->tbo.resource))
630629
amdgpu_cs_report_moved_bytes(adev, ctx.bytes_moved,
631630
ctx.bytes_moved);
632631
else
@@ -1280,23 +1279,25 @@ void amdgpu_bo_move_notify(struct ttm_buffer_object *bo, bool evict)
12801279
void amdgpu_bo_get_memory(struct amdgpu_bo *bo,
12811280
struct amdgpu_mem_stats *stats)
12821281
{
1282+
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
1283+
struct ttm_resource *res = bo->tbo.resource;
12831284
uint64_t size = amdgpu_bo_size(bo);
12841285
struct drm_gem_object *obj;
12851286
unsigned int domain;
12861287
bool shared;
12871288

12881289
/* Abort if the BO doesn't currently have a backing store */
1289-
if (!bo->tbo.resource)
1290+
if (!res)
12901291
return;
12911292

12921293
obj = &bo->tbo.base;
12931294
shared = drm_gem_object_is_shared_for_memory_stats(obj);
12941295

1295-
domain = amdgpu_mem_type_to_domain(bo->tbo.resource->mem_type);
1296+
domain = amdgpu_mem_type_to_domain(res->mem_type);
12961297
switch (domain) {
12971298
case AMDGPU_GEM_DOMAIN_VRAM:
12981299
stats->vram += size;
1299-
if (amdgpu_bo_in_cpu_visible_vram(bo))
1300+
if (amdgpu_res_cpu_visible(adev, bo->tbo.resource))
13001301
stats->visible_vram += size;
13011302
if (shared)
13021303
stats->vram_shared += size;
@@ -1395,10 +1396,7 @@ vm_fault_t amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo)
13951396
/* Remember that this BO was accessed by the CPU */
13961397
abo->flags |= AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED;
13971398

1398-
if (bo->resource->mem_type != TTM_PL_VRAM)
1399-
return 0;
1400-
1401-
if (amdgpu_bo_in_cpu_visible_vram(abo))
1399+
if (amdgpu_res_cpu_visible(adev, bo->resource))
14021400
return 0;
14031401

14041402
/* Can't move a pinned BO to visible VRAM */
@@ -1422,7 +1420,7 @@ vm_fault_t amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo)
14221420

14231421
/* this should never happen */
14241422
if (bo->resource->mem_type == TTM_PL_VRAM &&
1425-
!amdgpu_bo_in_cpu_visible_vram(abo))
1423+
!amdgpu_res_cpu_visible(adev, bo->resource))
14261424
return VM_FAULT_SIGBUS;
14271425

14281426
ttm_bo_move_to_lru_tail_unlocked(bo);
@@ -1582,6 +1580,7 @@ uint32_t amdgpu_bo_get_preferred_domain(struct amdgpu_device *adev,
15821580
*/
15831581
u64 amdgpu_bo_print_info(int id, struct amdgpu_bo *bo, struct seq_file *m)
15841582
{
1583+
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
15851584
struct dma_buf_attachment *attachment;
15861585
struct dma_buf *dma_buf;
15871586
const char *placement;
@@ -1590,10 +1589,11 @@ u64 amdgpu_bo_print_info(int id, struct amdgpu_bo *bo, struct seq_file *m)
15901589

15911590
if (dma_resv_trylock(bo->tbo.base.resv)) {
15921591
unsigned int domain;
1592+
15931593
domain = amdgpu_mem_type_to_domain(bo->tbo.resource->mem_type);
15941594
switch (domain) {
15951595
case AMDGPU_GEM_DOMAIN_VRAM:
1596-
if (amdgpu_bo_in_cpu_visible_vram(bo))
1596+
if (amdgpu_res_cpu_visible(adev, bo->tbo.resource))
15971597
placement = "VRAM VISIBLE";
15981598
else
15991599
placement = "VRAM";

drivers/gpu/drm/amd/amdgpu/amdgpu_object.h

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -250,28 +250,6 @@ static inline u64 amdgpu_bo_mmap_offset(struct amdgpu_bo *bo)
250250
return drm_vma_node_offset_addr(&bo->tbo.base.vma_node);
251251
}
252252

253-
/**
254-
* amdgpu_bo_in_cpu_visible_vram - check if BO is (partly) in visible VRAM
255-
*/
256-
static inline bool amdgpu_bo_in_cpu_visible_vram(struct amdgpu_bo *bo)
257-
{
258-
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
259-
struct amdgpu_res_cursor cursor;
260-
261-
if (!bo->tbo.resource || bo->tbo.resource->mem_type != TTM_PL_VRAM)
262-
return false;
263-
264-
amdgpu_res_first(bo->tbo.resource, 0, amdgpu_bo_size(bo), &cursor);
265-
while (cursor.remaining) {
266-
if (cursor.start < adev->gmc.visible_vram_size)
267-
return true;
268-
269-
amdgpu_res_next(&cursor, cursor.size);
270-
}
271-
272-
return false;
273-
}
274-
275253
/**
276254
* amdgpu_bo_explicit_sync - return whether the bo is explicitly synced
277255
*/

drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c

Lines changed: 38 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ static void amdgpu_evict_flags(struct ttm_buffer_object *bo,
137137
amdgpu_bo_placement_from_domain(abo, AMDGPU_GEM_DOMAIN_CPU);
138138
} else if (!amdgpu_gmc_vram_full_visible(&adev->gmc) &&
139139
!(abo->flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED) &&
140-
amdgpu_bo_in_cpu_visible_vram(abo)) {
140+
amdgpu_res_cpu_visible(adev, bo->resource)) {
141141

142142
/* Try evicting to the CPU inaccessible part of VRAM
143143
* first, but only set GTT as busy placement, so this
@@ -408,40 +408,55 @@ static int amdgpu_move_blit(struct ttm_buffer_object *bo,
408408
return r;
409409
}
410410

411-
/*
412-
* amdgpu_mem_visible - Check that memory can be accessed by ttm_bo_move_memcpy
411+
/**
412+
* amdgpu_res_cpu_visible - Check that resource can be accessed by CPU
413+
* @adev: amdgpu device
414+
* @res: the resource to check
413415
*
414-
* Called by amdgpu_bo_move()
416+
* Returns: true if the full resource is CPU visible, false otherwise.
415417
*/
416-
static bool amdgpu_mem_visible(struct amdgpu_device *adev,
417-
struct ttm_resource *mem)
418+
bool amdgpu_res_cpu_visible(struct amdgpu_device *adev,
419+
struct ttm_resource *res)
418420
{
419-
u64 mem_size = (u64)mem->size;
420421
struct amdgpu_res_cursor cursor;
421-
u64 end;
422422

423-
if (mem->mem_type == TTM_PL_SYSTEM ||
424-
mem->mem_type == TTM_PL_TT)
423+
if (!res)
424+
return false;
425+
426+
if (res->mem_type == TTM_PL_SYSTEM || res->mem_type == TTM_PL_TT ||
427+
res->mem_type == AMDGPU_PL_PREEMPT)
425428
return true;
426-
if (mem->mem_type != TTM_PL_VRAM)
429+
430+
if (res->mem_type != TTM_PL_VRAM)
427431
return false;
428432

429-
amdgpu_res_first(mem, 0, mem_size, &cursor);
430-
end = cursor.start + cursor.size;
433+
amdgpu_res_first(res, 0, res->size, &cursor);
431434
while (cursor.remaining) {
435+
if ((cursor.start + cursor.size) >= adev->gmc.visible_vram_size)
436+
return false;
432437
amdgpu_res_next(&cursor, cursor.size);
438+
}
433439

434-
if (!cursor.remaining)
435-
break;
440+
return true;
441+
}
436442

437-
/* ttm_resource_ioremap only supports contiguous memory */
438-
if (end != cursor.start)
439-
return false;
443+
/*
444+
* amdgpu_res_copyable - Check that memory can be accessed by ttm_bo_move_memcpy
445+
*
446+
* Called by amdgpu_bo_move()
447+
*/
448+
static bool amdgpu_res_copyable(struct amdgpu_device *adev,
449+
struct ttm_resource *mem)
450+
{
451+
if (!amdgpu_res_cpu_visible(adev, mem))
452+
return false;
440453

441-
end = cursor.start + cursor.size;
442-
}
454+
/* ttm_resource_ioremap only supports contiguous memory */
455+
if (mem->mem_type == TTM_PL_VRAM &&
456+
!(mem->placement & TTM_PL_FLAG_CONTIGUOUS))
457+
return false;
443458

444-
return end <= adev->gmc.visible_vram_size;
459+
return true;
445460
}
446461

447462
/*
@@ -534,8 +549,8 @@ static int amdgpu_bo_move(struct ttm_buffer_object *bo, bool evict,
534549

535550
if (r) {
536551
/* Check that all memory is CPU accessible */
537-
if (!amdgpu_mem_visible(adev, old_mem) ||
538-
!amdgpu_mem_visible(adev, new_mem)) {
552+
if (!amdgpu_res_copyable(adev, old_mem) ||
553+
!amdgpu_res_copyable(adev, new_mem)) {
539554
pr_err("Move buffer fallback to memcpy unavailable\n");
540555
return r;
541556
}

drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,9 @@ int amdgpu_vram_mgr_reserve_range(struct amdgpu_vram_mgr *mgr,
139139
int amdgpu_vram_mgr_query_page_status(struct amdgpu_vram_mgr *mgr,
140140
uint64_t start);
141141

142+
bool amdgpu_res_cpu_visible(struct amdgpu_device *adev,
143+
struct ttm_resource *res);
144+
142145
int amdgpu_ttm_init(struct amdgpu_device *adev);
143146
void amdgpu_ttm_fini(struct amdgpu_device *adev);
144147
void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev,

0 commit comments

Comments
 (0)