Commit 96cf8271 authored by John Brooks's avatar John Brooks Committed by Alex Deucher
Browse files

drm/amdgpu: Set/clear CPU_ACCESS flag on page fault and move to VRAM



When a BO is moved to VRAM, clear AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED.
This allows it to potentially later move to invisible VRAM if the CPU
does not access it again.

Setting the CPU_ACCESS flag in amdgpu_bo_fault_reserve_notify() also means
that we can remove the loop to restrict lpfn to the end of visible VRAM,
because amdgpu_ttm_placement_init() will do it for us.

v3 [Michel Dänzer]
* Use AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED instead of a new flag
  (Christian König)
* Clear flag in amdgpu_bo_move instead of amdgpu_move_ram_vram
  (Christian)
* Explicitly mention amdgpu_bo_fault_reserve_notify in amdgpu_bo_move
* Also clear flag in amdgpu_bo_create_restricted

Suggested-by: default avatarMichel Dänzer <michel.daenzer@amd.com>
Signed-off-by: default avatarJohn Brooks <john@fastquake.com>
Reviewed-by: default avatarChristian König <christian.koenig@amd.com>
Signed-off-by: default avatarMichel Dänzer <michel.daenzer@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 00f06b24
Loading
Loading
Loading
Loading
+10 −10
Original line number Original line Diff line number Diff line
@@ -432,6 +432,10 @@ int amdgpu_bo_create_restricted(struct amdgpu_device *adev,


	trace_amdgpu_bo_create(bo);
	trace_amdgpu_bo_create(bo);


	/* Treat CPU_ACCESS_REQUIRED only as a hint if given by UMD */
	if (type == ttm_bo_type_device)
		bo->flags &= ~AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED;

	return 0;
	return 0;


fail_unreserve:
fail_unreserve:
@@ -945,13 +949,17 @@ int amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo)
{
{
	struct amdgpu_device *adev = amdgpu_ttm_adev(bo->bdev);
	struct amdgpu_device *adev = amdgpu_ttm_adev(bo->bdev);
	struct amdgpu_bo *abo;
	struct amdgpu_bo *abo;
	unsigned long offset, size, lpfn;
	unsigned long offset, size;
	int i, r;
	int r;


	if (!amdgpu_ttm_bo_is_amdgpu_bo(bo))
	if (!amdgpu_ttm_bo_is_amdgpu_bo(bo))
		return 0;
		return 0;


	abo = container_of(bo, struct amdgpu_bo, tbo);
	abo = container_of(bo, struct amdgpu_bo, tbo);

	/* Remember that this BO was accessed by the CPU */
	abo->flags |= AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED;

	if (bo->mem.mem_type != TTM_PL_VRAM)
	if (bo->mem.mem_type != TTM_PL_VRAM)
		return 0;
		return 0;


@@ -967,14 +975,6 @@ int amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo)
	/* hurrah the memory is not visible ! */
	/* hurrah the memory is not visible ! */
	atomic64_inc(&adev->num_vram_cpu_page_faults);
	atomic64_inc(&adev->num_vram_cpu_page_faults);
	amdgpu_ttm_placement_from_domain(abo, AMDGPU_GEM_DOMAIN_VRAM);
	amdgpu_ttm_placement_from_domain(abo, AMDGPU_GEM_DOMAIN_VRAM);
	lpfn =	adev->mc.visible_vram_size >> PAGE_SHIFT;
	for (i = 0; i < abo->placement.num_placement; i++) {
		/* Force into visible VRAM */
		if ((abo->placements[i].flags & TTM_PL_FLAG_VRAM) &&
		    (!abo->placements[i].lpfn ||
		     abo->placements[i].lpfn > lpfn))
			abo->placements[i].lpfn = lpfn;
	}
	r = ttm_bo_validate(bo, &abo->placement, false, false);
	r = ttm_bo_validate(bo, &abo->placement, false, false);
	if (unlikely(r == -ENOMEM)) {
	if (unlikely(r == -ENOMEM)) {
		amdgpu_ttm_placement_from_domain(abo, AMDGPU_GEM_DOMAIN_GTT);
		amdgpu_ttm_placement_from_domain(abo, AMDGPU_GEM_DOMAIN_GTT);
+9 −0
Original line number Original line Diff line number Diff line
@@ -499,6 +499,15 @@ memcpy:
		}
		}
	}
	}


	if (bo->type == ttm_bo_type_device &&
	    new_mem->mem_type == TTM_PL_VRAM &&
	    old_mem->mem_type != TTM_PL_VRAM) {
		/* amdgpu_bo_fault_reserve_notify will re-set this if the CPU
		 * accesses the BO after it's moved.
		 */
		abo->flags &= ~AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED;
	}

	/* update statistics */
	/* update statistics */
	atomic64_add((u64)bo->num_pages << PAGE_SHIFT, &adev->num_bytes_moved);
	atomic64_add((u64)bo->num_pages << PAGE_SHIFT, &adev->num_bytes_moved);
	return 0;
	return 0;