diff mbox

[3/3] drm/amdgpu: rework amdgpu_cs_find_mapping

Message ID 1504713094-2455-3-git-send-email-deathsimple@vodafone.de (mailing list archive)
State New, archived
Headers show

Commit Message

Christian König Sept. 6, 2017, 3:51 p.m. UTC
From: Christian König <christian.koenig@amd.com>

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>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c     | 42 +++++++-----------------------
 drivers/gpu/drm/amd/amdgpu/amdgpu_object.h |  1 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c     | 17 ++++++++++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h     |  2 ++
 4 files changed, 30 insertions(+), 32 deletions(-)

Comments

Leo Liu Sept. 6, 2017, 4:33 p.m. UTC | #1
On 09/06/2017 11:51 AM, Christian König wrote:
> From: Christian König <christian.koenig@amd.com>
>
> 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.

The series is
Tested-by: Leo Liu <leo.liu@amd.com>

>
> Signed-off-by: Christian König <christian.koenig@amd.com>
> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c     | 42 +++++++-----------------------
>   drivers/gpu/drm/amd/amdgpu/amdgpu_object.h |  1 +
>   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c     | 17 ++++++++++++
>   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h     |  2 ++
>   4 files changed, 30 insertions(+), 32 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> index bcb3548..132e17a 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> @@ -1374,46 +1374,24 @@ int amdgpu_cs_find_mapping(struct amdgpu_cs_parser *parser,
>   			   uint64_t addr, struct amdgpu_bo **bo,
>   			   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;
> -	unsigned i;
>   	int r;
>   
> -	if (!parser->bo_list)
> -		return 0;
> -
>   	addr /= AMDGPU_GPU_PAGE_SIZE;
>   
> -	for (i = 0; i < parser->bo_list->num_entries; i++) {
> -		struct amdgpu_bo_list_entry *lobj;
> -
> -		lobj = &parser->bo_list->array[i];
> -		if (!lobj->bo_va)
> -			continue;
> -
> -		list_for_each_entry(mapping, &lobj->bo_va->valids, list) {
> -			if (mapping->start > addr ||
> -			    addr > mapping->last)
> -				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;
> +	mapping = amdgpu_vm_bo_lookup_mapping(vm, addr);
> +	if (!mapping || !mapping->bo_va || !mapping->bo_va->base.bo)
> +		return -EINVAL;
>   
> -			*bo = lobj->bo_va->base.bo;
> -			*map = mapping;
> -			goto found;
> -		}
> -	}
> +	*bo = mapping->bo_va->base.bo;
> +	*map = mapping;
>   
> -	return -EINVAL;
> +	/* Double check that the BO is reserved by this CS */
> +	if (READ_ONCE((*bo)->tbo.resv->lock.ctx) != &parser->ticket)
> +		return -EINVAL;
>   
> -found:
>   	r = amdgpu_ttm_bind(&(*bo)->tbo, &(*bo)->tbo.mem);
>   	if (unlikely(r))
>   		return r;
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
> index 42492e6..a4891be 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
> @@ -35,6 +35,7 @@
>   
>   /* bo virtual addresses in a vm */
>   struct amdgpu_bo_va_mapping {
> +	struct amdgpu_bo_va		*bo_va;
>   	struct list_head		list;
>   	struct rb_node			rb;
>   	uint64_t			start;
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
> index cfc8de8..ab9dfd7 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
> @@ -2083,6 +2083,7 @@ static void amdgpu_vm_bo_insert_map(struct amdgpu_device *adev,
>   	struct amdgpu_vm *vm = bo_va->base.vm;
>   	struct amdgpu_bo *bo = bo_va->base.bo;
>   
> +	mapping->bo_va = bo_va;
>   	list_add(&mapping->list, &bo_va->invalids);
>   	amdgpu_vm_it_insert(mapping, &vm->va);
>   
> @@ -2260,6 +2261,7 @@ int amdgpu_vm_bo_unmap(struct amdgpu_device *adev,
>   
>   	list_del(&mapping->list);
>   	amdgpu_vm_it_remove(mapping, &vm->va);
> +	mapping->bo_va = NULL;
>   	trace_amdgpu_vm_bo_unmap(bo_va, mapping);
>   
>   	if (valid)
> @@ -2345,6 +2347,7 @@ int amdgpu_vm_bo_clear_mappings(struct amdgpu_device *adev,
>   		if (tmp->last > eaddr)
>   		    tmp->last = eaddr;
>   
> +		tmp->bo_va = NULL;
>   		list_add(&tmp->list, &vm->freed);
>   		trace_amdgpu_vm_bo_unmap(NULL, tmp);
>   	}
> @@ -2371,6 +2374,19 @@ int amdgpu_vm_bo_clear_mappings(struct amdgpu_device *adev,
>   }
>   
>   /**
> + * 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
>    *
>    * @adev: amdgpu_device pointer
> @@ -2395,6 +2411,7 @@ void amdgpu_vm_bo_rmv(struct amdgpu_device *adev,
>   	list_for_each_entry_safe(mapping, next, &bo_va->valids, list) {
>   		list_del(&mapping->list);
>   		amdgpu_vm_it_remove(mapping, &vm->va);
> +		mapping->bo_va = NULL;
>   		trace_amdgpu_vm_bo_unmap(bo_va, mapping);
>   		list_add(&mapping->list, &vm->freed);
>   	}
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
> index 90b7741..c1accd1 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
> @@ -276,6 +276,8 @@ int amdgpu_vm_bo_unmap(struct amdgpu_device *adev,
>   int amdgpu_vm_bo_clear_mappings(struct amdgpu_device *adev,
>   				struct amdgpu_vm *vm,
>   				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,
>   		      struct amdgpu_bo_va *bo_va);
>   void amdgpu_vm_set_fragment_size(struct amdgpu_device *adev,
Christian König Sept. 7, 2017, 12:08 p.m. UTC | #2
Am 06.09.2017 um 18:33 schrieb Leo Liu:
>
>
> On 09/06/2017 11:51 AM, Christian König wrote:
>> From: Christian König <christian.koenig@amd.com>
>>
>> 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.
>
> The series is
> Tested-by: Leo Liu <leo.liu@amd.com>

Can I get an rb or ab as well? Alex is on vacation and I would really 
like to push this patch.

Christian.

>
>>
>> Signed-off-by: Christian König <christian.koenig@amd.com>
>> ---
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c     | 42 
>> +++++++-----------------------
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_object.h |  1 +
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c     | 17 ++++++++++++
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h     |  2 ++
>>   4 files changed, 30 insertions(+), 32 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c 
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
>> index bcb3548..132e17a 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
>> @@ -1374,46 +1374,24 @@ int amdgpu_cs_find_mapping(struct 
>> amdgpu_cs_parser *parser,
>>                  uint64_t addr, struct amdgpu_bo **bo,
>>                  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;
>> -    unsigned i;
>>       int r;
>>   -    if (!parser->bo_list)
>> -        return 0;
>> -
>>       addr /= AMDGPU_GPU_PAGE_SIZE;
>>   -    for (i = 0; i < parser->bo_list->num_entries; i++) {
>> -        struct amdgpu_bo_list_entry *lobj;
>> -
>> -        lobj = &parser->bo_list->array[i];
>> -        if (!lobj->bo_va)
>> -            continue;
>> -
>> -        list_for_each_entry(mapping, &lobj->bo_va->valids, list) {
>> -            if (mapping->start > addr ||
>> -                addr > mapping->last)
>> -                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;
>> +    mapping = amdgpu_vm_bo_lookup_mapping(vm, addr);
>> +    if (!mapping || !mapping->bo_va || !mapping->bo_va->base.bo)
>> +        return -EINVAL;
>>   -            *bo = lobj->bo_va->base.bo;
>> -            *map = mapping;
>> -            goto found;
>> -        }
>> -    }
>> +    *bo = mapping->bo_va->base.bo;
>> +    *map = mapping;
>>   -    return -EINVAL;
>> +    /* Double check that the BO is reserved by this CS */
>> +    if (READ_ONCE((*bo)->tbo.resv->lock.ctx) != &parser->ticket)
>> +        return -EINVAL;
>>   -found:
>>       r = amdgpu_ttm_bind(&(*bo)->tbo, &(*bo)->tbo.mem);
>>       if (unlikely(r))
>>           return r;
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h 
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
>> index 42492e6..a4891be 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
>> @@ -35,6 +35,7 @@
>>     /* bo virtual addresses in a vm */
>>   struct amdgpu_bo_va_mapping {
>> +    struct amdgpu_bo_va        *bo_va;
>>       struct list_head        list;
>>       struct rb_node            rb;
>>       uint64_t            start;
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c 
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
>> index cfc8de8..ab9dfd7 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
>> @@ -2083,6 +2083,7 @@ static void amdgpu_vm_bo_insert_map(struct 
>> amdgpu_device *adev,
>>       struct amdgpu_vm *vm = bo_va->base.vm;
>>       struct amdgpu_bo *bo = bo_va->base.bo;
>>   +    mapping->bo_va = bo_va;
>>       list_add(&mapping->list, &bo_va->invalids);
>>       amdgpu_vm_it_insert(mapping, &vm->va);
>>   @@ -2260,6 +2261,7 @@ int amdgpu_vm_bo_unmap(struct amdgpu_device 
>> *adev,
>>         list_del(&mapping->list);
>>       amdgpu_vm_it_remove(mapping, &vm->va);
>> +    mapping->bo_va = NULL;
>>       trace_amdgpu_vm_bo_unmap(bo_va, mapping);
>>         if (valid)
>> @@ -2345,6 +2347,7 @@ int amdgpu_vm_bo_clear_mappings(struct 
>> amdgpu_device *adev,
>>           if (tmp->last > eaddr)
>>               tmp->last = eaddr;
>>   +        tmp->bo_va = NULL;
>>           list_add(&tmp->list, &vm->freed);
>>           trace_amdgpu_vm_bo_unmap(NULL, tmp);
>>       }
>> @@ -2371,6 +2374,19 @@ int amdgpu_vm_bo_clear_mappings(struct 
>> amdgpu_device *adev,
>>   }
>>     /**
>> + * 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
>>    *
>>    * @adev: amdgpu_device pointer
>> @@ -2395,6 +2411,7 @@ void amdgpu_vm_bo_rmv(struct amdgpu_device *adev,
>>       list_for_each_entry_safe(mapping, next, &bo_va->valids, list) {
>>           list_del(&mapping->list);
>>           amdgpu_vm_it_remove(mapping, &vm->va);
>> +        mapping->bo_va = NULL;
>>           trace_amdgpu_vm_bo_unmap(bo_va, mapping);
>>           list_add(&mapping->list, &vm->freed);
>>       }
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h 
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
>> index 90b7741..c1accd1 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
>> @@ -276,6 +276,8 @@ int amdgpu_vm_bo_unmap(struct amdgpu_device *adev,
>>   int amdgpu_vm_bo_clear_mappings(struct amdgpu_device *adev,
>>                   struct amdgpu_vm *vm,
>>                   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,
>>                 struct amdgpu_bo_va *bo_va);
>>   void amdgpu_vm_set_fragment_size(struct amdgpu_device *adev,
>
Leo Liu Sept. 7, 2017, 12:25 p.m. UTC | #3
On 09/07/2017 08:08 AM, Christian König wrote:
> Am 06.09.2017 um 18:33 schrieb Leo Liu:
>>
>>
>> On 09/06/2017 11:51 AM, Christian König wrote:
>>> From: Christian König <christian.koenig@amd.com>
>>>
>>> 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.
>>
>> The series is
>> Tested-by: Leo Liu <leo.liu@amd.com>
>
> Can I get an rb or ab as well? Alex is on vacation and I would really 
> like to push this patch.
Since we need to fix the legacy UVD/VCE issue ASAP,
The series is
Acked-by: Leo Liu <leo.liu@amd.com>

>
> Christian.
>
>>
>>>
>>> Signed-off-by: Christian König <christian.koenig@amd.com>
>>> ---
>>>   drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c     | 42 
>>> +++++++-----------------------
>>>   drivers/gpu/drm/amd/amdgpu/amdgpu_object.h |  1 +
>>>   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c     | 17 ++++++++++++
>>>   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h     |  2 ++
>>>   4 files changed, 30 insertions(+), 32 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c 
>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
>>> index bcb3548..132e17a 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
>>> @@ -1374,46 +1374,24 @@ int amdgpu_cs_find_mapping(struct 
>>> amdgpu_cs_parser *parser,
>>>                  uint64_t addr, struct amdgpu_bo **bo,
>>>                  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;
>>> -    unsigned i;
>>>       int r;
>>>   -    if (!parser->bo_list)
>>> -        return 0;
>>> -
>>>       addr /= AMDGPU_GPU_PAGE_SIZE;
>>>   -    for (i = 0; i < parser->bo_list->num_entries; i++) {
>>> -        struct amdgpu_bo_list_entry *lobj;
>>> -
>>> -        lobj = &parser->bo_list->array[i];
>>> -        if (!lobj->bo_va)
>>> -            continue;
>>> -
>>> -        list_for_each_entry(mapping, &lobj->bo_va->valids, list) {
>>> -            if (mapping->start > addr ||
>>> -                addr > mapping->last)
>>> -                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;
>>> +    mapping = amdgpu_vm_bo_lookup_mapping(vm, addr);
>>> +    if (!mapping || !mapping->bo_va || !mapping->bo_va->base.bo)
>>> +        return -EINVAL;
>>>   -            *bo = lobj->bo_va->base.bo;
>>> -            *map = mapping;
>>> -            goto found;
>>> -        }
>>> -    }
>>> +    *bo = mapping->bo_va->base.bo;
>>> +    *map = mapping;
>>>   -    return -EINVAL;
>>> +    /* Double check that the BO is reserved by this CS */
>>> +    if (READ_ONCE((*bo)->tbo.resv->lock.ctx) != &parser->ticket)
>>> +        return -EINVAL;
>>>   -found:
>>>       r = amdgpu_ttm_bind(&(*bo)->tbo, &(*bo)->tbo.mem);
>>>       if (unlikely(r))
>>>           return r;
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h 
>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
>>> index 42492e6..a4891be 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
>>> @@ -35,6 +35,7 @@
>>>     /* bo virtual addresses in a vm */
>>>   struct amdgpu_bo_va_mapping {
>>> +    struct amdgpu_bo_va        *bo_va;
>>>       struct list_head        list;
>>>       struct rb_node            rb;
>>>       uint64_t            start;
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c 
>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
>>> index cfc8de8..ab9dfd7 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
>>> @@ -2083,6 +2083,7 @@ static void amdgpu_vm_bo_insert_map(struct 
>>> amdgpu_device *adev,
>>>       struct amdgpu_vm *vm = bo_va->base.vm;
>>>       struct amdgpu_bo *bo = bo_va->base.bo;
>>>   +    mapping->bo_va = bo_va;
>>>       list_add(&mapping->list, &bo_va->invalids);
>>>       amdgpu_vm_it_insert(mapping, &vm->va);
>>>   @@ -2260,6 +2261,7 @@ int amdgpu_vm_bo_unmap(struct amdgpu_device 
>>> *adev,
>>>         list_del(&mapping->list);
>>>       amdgpu_vm_it_remove(mapping, &vm->va);
>>> +    mapping->bo_va = NULL;
>>>       trace_amdgpu_vm_bo_unmap(bo_va, mapping);
>>>         if (valid)
>>> @@ -2345,6 +2347,7 @@ int amdgpu_vm_bo_clear_mappings(struct 
>>> amdgpu_device *adev,
>>>           if (tmp->last > eaddr)
>>>               tmp->last = eaddr;
>>>   +        tmp->bo_va = NULL;
>>>           list_add(&tmp->list, &vm->freed);
>>>           trace_amdgpu_vm_bo_unmap(NULL, tmp);
>>>       }
>>> @@ -2371,6 +2374,19 @@ int amdgpu_vm_bo_clear_mappings(struct 
>>> amdgpu_device *adev,
>>>   }
>>>     /**
>>> + * 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
>>>    *
>>>    * @adev: amdgpu_device pointer
>>> @@ -2395,6 +2411,7 @@ void amdgpu_vm_bo_rmv(struct amdgpu_device *adev,
>>>       list_for_each_entry_safe(mapping, next, &bo_va->valids, list) {
>>>           list_del(&mapping->list);
>>>           amdgpu_vm_it_remove(mapping, &vm->va);
>>> +        mapping->bo_va = NULL;
>>>           trace_amdgpu_vm_bo_unmap(bo_va, mapping);
>>>           list_add(&mapping->list, &vm->freed);
>>>       }
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h 
>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
>>> index 90b7741..c1accd1 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
>>> @@ -276,6 +276,8 @@ int amdgpu_vm_bo_unmap(struct amdgpu_device *adev,
>>>   int amdgpu_vm_bo_clear_mappings(struct amdgpu_device *adev,
>>>                   struct amdgpu_vm *vm,
>>>                   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,
>>>                 struct amdgpu_bo_va *bo_va);
>>>   void amdgpu_vm_set_fragment_size(struct amdgpu_device *adev,
>>
>
diff mbox

Patch

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index bcb3548..132e17a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -1374,46 +1374,24 @@  int amdgpu_cs_find_mapping(struct amdgpu_cs_parser *parser,
 			   uint64_t addr, struct amdgpu_bo **bo,
 			   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;
-	unsigned i;
 	int r;
 
-	if (!parser->bo_list)
-		return 0;
-
 	addr /= AMDGPU_GPU_PAGE_SIZE;
 
-	for (i = 0; i < parser->bo_list->num_entries; i++) {
-		struct amdgpu_bo_list_entry *lobj;
-
-		lobj = &parser->bo_list->array[i];
-		if (!lobj->bo_va)
-			continue;
-
-		list_for_each_entry(mapping, &lobj->bo_va->valids, list) {
-			if (mapping->start > addr ||
-			    addr > mapping->last)
-				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;
+	mapping = amdgpu_vm_bo_lookup_mapping(vm, addr);
+	if (!mapping || !mapping->bo_va || !mapping->bo_va->base.bo)
+		return -EINVAL;
 
-			*bo = lobj->bo_va->base.bo;
-			*map = mapping;
-			goto found;
-		}
-	}
+	*bo = mapping->bo_va->base.bo;
+	*map = mapping;
 
-	return -EINVAL;
+	/* Double check that the BO is reserved by this CS */
+	if (READ_ONCE((*bo)->tbo.resv->lock.ctx) != &parser->ticket)
+		return -EINVAL;
 
-found:
 	r = amdgpu_ttm_bind(&(*bo)->tbo, &(*bo)->tbo.mem);
 	if (unlikely(r))
 		return r;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
index 42492e6..a4891be 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
@@ -35,6 +35,7 @@ 
 
 /* bo virtual addresses in a vm */
 struct amdgpu_bo_va_mapping {
+	struct amdgpu_bo_va		*bo_va;
 	struct list_head		list;
 	struct rb_node			rb;
 	uint64_t			start;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index cfc8de8..ab9dfd7 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -2083,6 +2083,7 @@  static void amdgpu_vm_bo_insert_map(struct amdgpu_device *adev,
 	struct amdgpu_vm *vm = bo_va->base.vm;
 	struct amdgpu_bo *bo = bo_va->base.bo;
 
+	mapping->bo_va = bo_va;
 	list_add(&mapping->list, &bo_va->invalids);
 	amdgpu_vm_it_insert(mapping, &vm->va);
 
@@ -2260,6 +2261,7 @@  int amdgpu_vm_bo_unmap(struct amdgpu_device *adev,
 
 	list_del(&mapping->list);
 	amdgpu_vm_it_remove(mapping, &vm->va);
+	mapping->bo_va = NULL;
 	trace_amdgpu_vm_bo_unmap(bo_va, mapping);
 
 	if (valid)
@@ -2345,6 +2347,7 @@  int amdgpu_vm_bo_clear_mappings(struct amdgpu_device *adev,
 		if (tmp->last > eaddr)
 		    tmp->last = eaddr;
 
+		tmp->bo_va = NULL;
 		list_add(&tmp->list, &vm->freed);
 		trace_amdgpu_vm_bo_unmap(NULL, tmp);
 	}
@@ -2371,6 +2374,19 @@  int amdgpu_vm_bo_clear_mappings(struct amdgpu_device *adev,
 }
 
 /**
+ * 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
  *
  * @adev: amdgpu_device pointer
@@ -2395,6 +2411,7 @@  void amdgpu_vm_bo_rmv(struct amdgpu_device *adev,
 	list_for_each_entry_safe(mapping, next, &bo_va->valids, list) {
 		list_del(&mapping->list);
 		amdgpu_vm_it_remove(mapping, &vm->va);
+		mapping->bo_va = NULL;
 		trace_amdgpu_vm_bo_unmap(bo_va, mapping);
 		list_add(&mapping->list, &vm->freed);
 	}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
index 90b7741..c1accd1 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
@@ -276,6 +276,8 @@  int amdgpu_vm_bo_unmap(struct amdgpu_device *adev,
 int amdgpu_vm_bo_clear_mappings(struct amdgpu_device *adev,
 				struct amdgpu_vm *vm,
 				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,
 		      struct amdgpu_bo_va *bo_va);
 void amdgpu_vm_set_fragment_size(struct amdgpu_device *adev,