mirror of https://gitee.com/openkylin/linux.git
drm/amdgpu: move PT validation back into VM code v2
Saves a bunch of CPU cycles when swapping things back in and allows us to split the VM headers into a separate file. v2: rename parameters 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>
This commit is contained in:
parent
a7d64de659
commit
f7da30d979
|
@ -915,8 +915,9 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm);
|
|||
void amdgpu_vm_get_pd_bo(struct amdgpu_vm *vm,
|
||||
struct list_head *validated,
|
||||
struct amdgpu_bo_list_entry *entry);
|
||||
void amdgpu_vm_get_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm,
|
||||
struct list_head *duplicates);
|
||||
int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm,
|
||||
int (*callback)(void *p, struct amdgpu_bo *bo),
|
||||
void *param);
|
||||
void amdgpu_vm_move_pt_bos_in_lru(struct amdgpu_device *adev,
|
||||
struct amdgpu_vm *vm);
|
||||
int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring,
|
||||
|
|
|
@ -388,9 +388,9 @@ static int amdgpu_cs_bo_validate(struct amdgpu_cs_parser *p,
|
|||
|
||||
/* Last resort, try to evict something from the current working set */
|
||||
static bool amdgpu_cs_try_evict(struct amdgpu_cs_parser *p,
|
||||
struct amdgpu_bo_list_entry *lobj)
|
||||
struct amdgpu_bo *validated)
|
||||
{
|
||||
uint32_t domain = lobj->robj->allowed_domains;
|
||||
uint32_t domain = validated->allowed_domains;
|
||||
int r;
|
||||
|
||||
if (!p->evictable)
|
||||
|
@ -406,7 +406,7 @@ static bool amdgpu_cs_try_evict(struct amdgpu_cs_parser *p,
|
|||
uint32_t other;
|
||||
|
||||
/* If we reached our current BO we can forget it */
|
||||
if (candidate == lobj)
|
||||
if (candidate->robj == validated)
|
||||
break;
|
||||
|
||||
other = amdgpu_mem_type_to_domain(bo->tbo.mem.mem_type);
|
||||
|
@ -439,6 +439,23 @@ static bool amdgpu_cs_try_evict(struct amdgpu_cs_parser *p,
|
|||
return false;
|
||||
}
|
||||
|
||||
static int amdgpu_cs_validate(void *param, struct amdgpu_bo *bo)
|
||||
{
|
||||
struct amdgpu_cs_parser *p = param;
|
||||
int r;
|
||||
|
||||
do {
|
||||
r = amdgpu_cs_bo_validate(p, bo);
|
||||
} while (r == -ENOMEM && amdgpu_cs_try_evict(p, bo));
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
if (bo->shadow)
|
||||
r = amdgpu_cs_bo_validate(p, bo);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int amdgpu_cs_list_validate(struct amdgpu_cs_parser *p,
|
||||
struct list_head *validated)
|
||||
{
|
||||
|
@ -466,18 +483,10 @@ static int amdgpu_cs_list_validate(struct amdgpu_cs_parser *p,
|
|||
if (p->evictable == lobj)
|
||||
p->evictable = NULL;
|
||||
|
||||
do {
|
||||
r = amdgpu_cs_bo_validate(p, bo);
|
||||
} while (r == -ENOMEM && amdgpu_cs_try_evict(p, lobj));
|
||||
r = amdgpu_cs_validate(p, bo);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
if (bo->shadow) {
|
||||
r = amdgpu_cs_bo_validate(p, bo);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (binding_userptr) {
|
||||
drm_free_large(lobj->user_pages);
|
||||
lobj->user_pages = NULL;
|
||||
|
@ -595,14 +604,19 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
|
|||
list_splice(&need_pages, &p->validated);
|
||||
}
|
||||
|
||||
amdgpu_vm_get_pt_bos(p->adev, &fpriv->vm, &duplicates);
|
||||
|
||||
p->bytes_moved_threshold = amdgpu_cs_get_threshold_for_moves(p->adev);
|
||||
p->bytes_moved = 0;
|
||||
p->evictable = list_last_entry(&p->validated,
|
||||
struct amdgpu_bo_list_entry,
|
||||
tv.head);
|
||||
|
||||
r = amdgpu_vm_validate_pt_bos(p->adev, &fpriv->vm,
|
||||
amdgpu_cs_validate, p);
|
||||
if (r) {
|
||||
DRM_ERROR("amdgpu_vm_validate_pt_bos() failed.\n");
|
||||
goto error_validate;
|
||||
}
|
||||
|
||||
r = amdgpu_cs_list_validate(p, &duplicates);
|
||||
if (r) {
|
||||
DRM_ERROR("amdgpu_cs_list_validate(duplicates) failed.\n");
|
||||
|
|
|
@ -469,6 +469,16 @@ int amdgpu_gem_metadata_ioctl(struct drm_device *dev, void *data,
|
|||
return r;
|
||||
}
|
||||
|
||||
static int amdgpu_gem_va_check(void *param, struct amdgpu_bo *bo)
|
||||
{
|
||||
unsigned domain = amdgpu_mem_type_to_domain(bo->tbo.mem.mem_type);
|
||||
|
||||
/* if anything is swapped out don't swap it in here,
|
||||
just abort and wait for the next CS */
|
||||
|
||||
return domain == AMDGPU_GEM_DOMAIN_CPU ? -ERESTARTSYS : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_gem_va_update_vm -update the bo_va in its VM
|
||||
*
|
||||
|
@ -479,7 +489,8 @@ int amdgpu_gem_metadata_ioctl(struct drm_device *dev, void *data,
|
|||
* vital here, so they are not reported back to userspace.
|
||||
*/
|
||||
static void amdgpu_gem_va_update_vm(struct amdgpu_device *adev,
|
||||
struct amdgpu_bo_va *bo_va, uint32_t operation)
|
||||
struct amdgpu_bo_va *bo_va,
|
||||
uint32_t operation)
|
||||
{
|
||||
struct ttm_validate_buffer tv, *entry;
|
||||
struct amdgpu_bo_list_entry vm_pd;
|
||||
|
@ -502,7 +513,6 @@ static void amdgpu_gem_va_update_vm(struct amdgpu_device *adev,
|
|||
if (r)
|
||||
goto error_print;
|
||||
|
||||
amdgpu_vm_get_pt_bos(adev, bo_va->vm, &duplicates);
|
||||
list_for_each_entry(entry, &list, head) {
|
||||
domain = amdgpu_mem_type_to_domain(entry->bo->mem.mem_type);
|
||||
/* if anything is swapped out don't swap it in here,
|
||||
|
@ -510,13 +520,10 @@ static void amdgpu_gem_va_update_vm(struct amdgpu_device *adev,
|
|||
if (domain == AMDGPU_GEM_DOMAIN_CPU)
|
||||
goto error_unreserve;
|
||||
}
|
||||
list_for_each_entry(entry, &duplicates, head) {
|
||||
domain = amdgpu_mem_type_to_domain(entry->bo->mem.mem_type);
|
||||
/* if anything is swapped out don't swap it in here,
|
||||
just abort and wait for the next CS */
|
||||
if (domain == AMDGPU_GEM_DOMAIN_CPU)
|
||||
goto error_unreserve;
|
||||
}
|
||||
r = amdgpu_vm_validate_pt_bos(adev, bo_va->vm, amdgpu_gem_va_check,
|
||||
NULL);
|
||||
if (r)
|
||||
goto error_unreserve;
|
||||
|
||||
r = amdgpu_vm_update_page_directory(adev, bo_va->vm);
|
||||
if (r)
|
||||
|
@ -537,8 +544,6 @@ static void amdgpu_gem_va_update_vm(struct amdgpu_device *adev,
|
|||
DRM_ERROR("Couldn't update BO_VA (%d)\n", r);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *filp)
|
||||
{
|
||||
|
|
|
@ -116,27 +116,29 @@ void amdgpu_vm_get_pd_bo(struct amdgpu_vm *vm,
|
|||
}
|
||||
|
||||
/**
|
||||
* amdgpu_vm_get_bos - add the vm BOs to a duplicates list
|
||||
* amdgpu_vm_validate_pt_bos - validate the page table BOs
|
||||
*
|
||||
* @adev: amdgpu device pointer
|
||||
* @vm: vm providing the BOs
|
||||
* @duplicates: head of duplicates list
|
||||
* @validate: callback to do the validation
|
||||
* @param: parameter for the validation callback
|
||||
*
|
||||
* Add the page directory to the BO duplicates list
|
||||
* for command submission.
|
||||
* Validate the page table BOs on command submission if neccessary.
|
||||
*/
|
||||
void amdgpu_vm_get_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm,
|
||||
struct list_head *duplicates)
|
||||
int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm,
|
||||
int (*validate)(void *p, struct amdgpu_bo *bo),
|
||||
void *param)
|
||||
{
|
||||
uint64_t num_evictions;
|
||||
unsigned i;
|
||||
int r;
|
||||
|
||||
/* We only need to validate the page tables
|
||||
* if they aren't already valid.
|
||||
*/
|
||||
num_evictions = atomic64_read(&adev->num_evictions);
|
||||
if (num_evictions == vm->last_eviction_counter)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
/* add the vm page table to the list */
|
||||
for (i = 0; i <= vm->max_pde_used; ++i) {
|
||||
|
@ -145,9 +147,12 @@ void amdgpu_vm_get_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm,
|
|||
if (!entry->robj)
|
||||
continue;
|
||||
|
||||
list_add(&entry->tv.head, duplicates);
|
||||
r = validate(param, entry->robj);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue