Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bf60efd3 authored by Christian König's avatar Christian König Committed by Alex Deucher
Browse files

drm/amdgpu: use only one reservation object for each VM v2



Reduces the locking and fencing overhead.

v2: add comment why we need the duplicates list in the GEM op.

Signed-off-by: default avatarChristian König <christian.koenig@amd.com>
Reviewed-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Reviewed-by: default avatarJammy Zhou <Jammy.Zhou@amd.com>
parent a5b75058
Loading
Loading
Loading
Loading
+4 −2
Original line number Original line Diff line number Diff line
@@ -455,11 +455,12 @@ static void amdgpu_gem_va_update_vm(struct amdgpu_device *adev,
	struct ttm_validate_buffer tv, *entry;
	struct ttm_validate_buffer tv, *entry;
	struct amdgpu_bo_list_entry *vm_bos;
	struct amdgpu_bo_list_entry *vm_bos;
	struct ww_acquire_ctx ticket;
	struct ww_acquire_ctx ticket;
	struct list_head list;
	struct list_head list, duplicates;
	unsigned domain;
	unsigned domain;
	int r;
	int r;


	INIT_LIST_HEAD(&list);
	INIT_LIST_HEAD(&list);
	INIT_LIST_HEAD(&duplicates);


	tv.bo = &bo_va->bo->tbo;
	tv.bo = &bo_va->bo->tbo;
	tv.shared = true;
	tv.shared = true;
@@ -469,7 +470,8 @@ static void amdgpu_gem_va_update_vm(struct amdgpu_device *adev,
	if (!vm_bos)
	if (!vm_bos)
		return;
		return;


	r = ttm_eu_reserve_buffers(&ticket, &list, true, NULL);
	/* Provide duplicates to avoid -EALREADY */
	r = ttm_eu_reserve_buffers(&ticket, &list, true, &duplicates);
	if (r)
	if (r)
		goto error_free;
		goto error_free;


+5 −28
Original line number Original line Diff line number Diff line
@@ -685,31 +685,6 @@ static int amdgpu_vm_update_ptes(struct amdgpu_device *adev,
	return 0;
	return 0;
}
}


/**
 * amdgpu_vm_fence_pts - fence page tables after an update
 *
 * @vm: requested vm
 * @start: start of GPU address range
 * @end: end of GPU address range
 * @fence: fence to use
 *
 * Fence the page tables in the range @start - @end (cayman+).
 *
 * Global and local mutex must be locked!
 */
static void amdgpu_vm_fence_pts(struct amdgpu_vm *vm,
				uint64_t start, uint64_t end,
				struct fence *fence)
{
	unsigned i;

	start >>= amdgpu_vm_block_size;
	end >>= amdgpu_vm_block_size;

	for (i = start; i <= end; ++i)
		amdgpu_bo_fence(vm->page_tables[i].bo, fence, true);
}

/**
/**
 * amdgpu_vm_bo_update_mapping - update a mapping in the vm page table
 * amdgpu_vm_bo_update_mapping - update a mapping in the vm page table
 *
 *
@@ -813,8 +788,7 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
	if (r)
	if (r)
		goto error_free;
		goto error_free;


	amdgpu_vm_fence_pts(vm, mapping->it.start,
	amdgpu_bo_fence(vm->page_directory, f, true);
			    mapping->it.last + 1, f);
	if (fence) {
	if (fence) {
		fence_put(*fence);
		fence_put(*fence);
		*fence = fence_get(f);
		*fence = fence_get(f);
@@ -1089,6 +1063,7 @@ int amdgpu_vm_bo_map(struct amdgpu_device *adev,


	/* walk over the address space and allocate the page tables */
	/* walk over the address space and allocate the page tables */
	for (pt_idx = saddr; pt_idx <= eaddr; ++pt_idx) {
	for (pt_idx = saddr; pt_idx <= eaddr; ++pt_idx) {
		struct reservation_object *resv = vm->page_directory->tbo.resv;
		struct amdgpu_bo *pt;
		struct amdgpu_bo *pt;


		if (vm->page_tables[pt_idx].bo)
		if (vm->page_tables[pt_idx].bo)
@@ -1097,11 +1072,13 @@ int amdgpu_vm_bo_map(struct amdgpu_device *adev,
		/* drop mutex to allocate and clear page table */
		/* drop mutex to allocate and clear page table */
		mutex_unlock(&vm->mutex);
		mutex_unlock(&vm->mutex);


		ww_mutex_lock(&resv->lock, NULL);
		r = amdgpu_bo_create(adev, AMDGPU_VM_PTE_COUNT * 8,
		r = amdgpu_bo_create(adev, AMDGPU_VM_PTE_COUNT * 8,
				     AMDGPU_GPU_PAGE_SIZE, true,
				     AMDGPU_GPU_PAGE_SIZE, true,
				     AMDGPU_GEM_DOMAIN_VRAM,
				     AMDGPU_GEM_DOMAIN_VRAM,
				     AMDGPU_GEM_CREATE_NO_CPU_ACCESS,
				     AMDGPU_GEM_CREATE_NO_CPU_ACCESS,
				     NULL, NULL, &pt);
				     NULL, resv, &pt);
		ww_mutex_unlock(&resv->lock);
		if (r)
		if (r)
			goto error_free;
			goto error_free;