drm/amdgpu: rework amdgpu_cs_find_mapping
Use the VM instead of the BO list to find the BO for a virtual address. This fixes UVD/VCE in physical mode with VM local BOs. Signed-off-by: Christian König <christian.koenig@amd.com> Acked-by: Leo Liu <leo.liu@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
9cca0b8e5d
commit
aebc5e6f50
|
@ -1479,46 +1479,24 @@ int amdgpu_cs_find_mapping(struct amdgpu_cs_parser *parser,
|
||||||
uint64_t addr, struct amdgpu_bo **bo,
|
uint64_t addr, struct amdgpu_bo **bo,
|
||||||
struct amdgpu_bo_va_mapping **map)
|
struct amdgpu_bo_va_mapping **map)
|
||||||
{
|
{
|
||||||
|
struct amdgpu_fpriv *fpriv = parser->filp->driver_priv;
|
||||||
|
struct amdgpu_vm *vm = &fpriv->vm;
|
||||||
struct amdgpu_bo_va_mapping *mapping;
|
struct amdgpu_bo_va_mapping *mapping;
|
||||||
unsigned i;
|
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
if (!parser->bo_list)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
addr /= AMDGPU_GPU_PAGE_SIZE;
|
addr /= AMDGPU_GPU_PAGE_SIZE;
|
||||||
|
|
||||||
for (i = 0; i < parser->bo_list->num_entries; i++) {
|
mapping = amdgpu_vm_bo_lookup_mapping(vm, addr);
|
||||||
struct amdgpu_bo_list_entry *lobj;
|
if (!mapping || !mapping->bo_va || !mapping->bo_va->base.bo)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
lobj = &parser->bo_list->array[i];
|
*bo = mapping->bo_va->base.bo;
|
||||||
if (!lobj->bo_va)
|
*map = mapping;
|
||||||
continue;
|
|
||||||
|
|
||||||
list_for_each_entry(mapping, &lobj->bo_va->valids, list) {
|
/* Double check that the BO is reserved by this CS */
|
||||||
if (mapping->start > addr ||
|
if (READ_ONCE((*bo)->tbo.resv->lock.ctx) != &parser->ticket)
|
||||||
addr > mapping->last)
|
return -EINVAL;
|
||||||
continue;
|
|
||||||
|
|
||||||
*bo = lobj->bo_va->base.bo;
|
|
||||||
*map = mapping;
|
|
||||||
goto found;
|
|
||||||
}
|
|
||||||
|
|
||||||
list_for_each_entry(mapping, &lobj->bo_va->invalids, list) {
|
|
||||||
if (mapping->start > addr ||
|
|
||||||
addr > mapping->last)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
*bo = lobj->bo_va->base.bo;
|
|
||||||
*map = mapping;
|
|
||||||
goto found;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
found:
|
|
||||||
r = amdgpu_ttm_bind(&(*bo)->tbo, &(*bo)->tbo.mem);
|
r = amdgpu_ttm_bind(&(*bo)->tbo, &(*bo)->tbo.mem);
|
||||||
if (unlikely(r))
|
if (unlikely(r))
|
||||||
return r;
|
return r;
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
|
|
||||||
/* bo virtual addresses in a vm */
|
/* bo virtual addresses in a vm */
|
||||||
struct amdgpu_bo_va_mapping {
|
struct amdgpu_bo_va_mapping {
|
||||||
|
struct amdgpu_bo_va *bo_va;
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
struct rb_node rb;
|
struct rb_node rb;
|
||||||
uint64_t start;
|
uint64_t start;
|
||||||
|
|
|
@ -2086,6 +2086,7 @@ static void amdgpu_vm_bo_insert_map(struct amdgpu_device *adev,
|
||||||
struct amdgpu_vm *vm = bo_va->base.vm;
|
struct amdgpu_vm *vm = bo_va->base.vm;
|
||||||
struct amdgpu_bo *bo = bo_va->base.bo;
|
struct amdgpu_bo *bo = bo_va->base.bo;
|
||||||
|
|
||||||
|
mapping->bo_va = bo_va;
|
||||||
list_add(&mapping->list, &bo_va->invalids);
|
list_add(&mapping->list, &bo_va->invalids);
|
||||||
amdgpu_vm_it_insert(mapping, &vm->va);
|
amdgpu_vm_it_insert(mapping, &vm->va);
|
||||||
|
|
||||||
|
@ -2263,6 +2264,7 @@ int amdgpu_vm_bo_unmap(struct amdgpu_device *adev,
|
||||||
|
|
||||||
list_del(&mapping->list);
|
list_del(&mapping->list);
|
||||||
amdgpu_vm_it_remove(mapping, &vm->va);
|
amdgpu_vm_it_remove(mapping, &vm->va);
|
||||||
|
mapping->bo_va = NULL;
|
||||||
trace_amdgpu_vm_bo_unmap(bo_va, mapping);
|
trace_amdgpu_vm_bo_unmap(bo_va, mapping);
|
||||||
|
|
||||||
if (valid)
|
if (valid)
|
||||||
|
@ -2348,6 +2350,7 @@ int amdgpu_vm_bo_clear_mappings(struct amdgpu_device *adev,
|
||||||
if (tmp->last > eaddr)
|
if (tmp->last > eaddr)
|
||||||
tmp->last = eaddr;
|
tmp->last = eaddr;
|
||||||
|
|
||||||
|
tmp->bo_va = NULL;
|
||||||
list_add(&tmp->list, &vm->freed);
|
list_add(&tmp->list, &vm->freed);
|
||||||
trace_amdgpu_vm_bo_unmap(NULL, tmp);
|
trace_amdgpu_vm_bo_unmap(NULL, tmp);
|
||||||
}
|
}
|
||||||
|
@ -2373,6 +2376,19 @@ int amdgpu_vm_bo_clear_mappings(struct amdgpu_device *adev,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* amdgpu_vm_bo_lookup_mapping - find mapping by address
|
||||||
|
*
|
||||||
|
* @vm: the requested VM
|
||||||
|
*
|
||||||
|
* Find a mapping by it's address.
|
||||||
|
*/
|
||||||
|
struct amdgpu_bo_va_mapping *amdgpu_vm_bo_lookup_mapping(struct amdgpu_vm *vm,
|
||||||
|
uint64_t addr)
|
||||||
|
{
|
||||||
|
return amdgpu_vm_it_iter_first(&vm->va, addr, addr);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* amdgpu_vm_bo_rmv - remove a bo to a specific vm
|
* amdgpu_vm_bo_rmv - remove a bo to a specific vm
|
||||||
*
|
*
|
||||||
|
@ -2398,6 +2414,7 @@ void amdgpu_vm_bo_rmv(struct amdgpu_device *adev,
|
||||||
list_for_each_entry_safe(mapping, next, &bo_va->valids, list) {
|
list_for_each_entry_safe(mapping, next, &bo_va->valids, list) {
|
||||||
list_del(&mapping->list);
|
list_del(&mapping->list);
|
||||||
amdgpu_vm_it_remove(mapping, &vm->va);
|
amdgpu_vm_it_remove(mapping, &vm->va);
|
||||||
|
mapping->bo_va = NULL;
|
||||||
trace_amdgpu_vm_bo_unmap(bo_va, mapping);
|
trace_amdgpu_vm_bo_unmap(bo_va, mapping);
|
||||||
list_add(&mapping->list, &vm->freed);
|
list_add(&mapping->list, &vm->freed);
|
||||||
}
|
}
|
||||||
|
|
|
@ -276,6 +276,8 @@ int amdgpu_vm_bo_unmap(struct amdgpu_device *adev,
|
||||||
int amdgpu_vm_bo_clear_mappings(struct amdgpu_device *adev,
|
int amdgpu_vm_bo_clear_mappings(struct amdgpu_device *adev,
|
||||||
struct amdgpu_vm *vm,
|
struct amdgpu_vm *vm,
|
||||||
uint64_t saddr, uint64_t size);
|
uint64_t saddr, uint64_t size);
|
||||||
|
struct amdgpu_bo_va_mapping *amdgpu_vm_bo_lookup_mapping(struct amdgpu_vm *vm,
|
||||||
|
uint64_t addr);
|
||||||
void amdgpu_vm_bo_rmv(struct amdgpu_device *adev,
|
void amdgpu_vm_bo_rmv(struct amdgpu_device *adev,
|
||||||
struct amdgpu_bo_va *bo_va);
|
struct amdgpu_bo_va *bo_va);
|
||||||
void amdgpu_vm_set_fragment_size(struct amdgpu_device *adev,
|
void amdgpu_vm_set_fragment_size(struct amdgpu_device *adev,
|
||||||
|
|
Loading…
Reference in New Issue