[PATCH 4/7] drm/radeon: Pin buffers while they are vmap'ed

Thomas Zimmermann tzimmermann at suse.de
Fri Nov 13 07:59:20 UTC 2020


Hi Christian

Am 12.11.20 um 18:16 schrieb Christian König:
> Am 12.11.20 um 14:21 schrieb Thomas Zimmermann:
>> In order to avoid eviction of vmap'ed buffers, pin them in their GEM
>> object's vmap implementation. Unpin them in the vunmap implementation.
>> This is needed to make generic fbdev support work reliably. Without,
>> the buffer object could be evicted while fbdev flushed its shadow buffer.
>>
>> In difference to the PRIME pin/unpin functions, the vmap code does not
>> modify the BOs prime_shared_count, so a vmap-pinned BO does not count as
>> shared.
>>
>> The actual pin location is not important as the vmap call returns
>> information on how to access the buffer. Callers that require a
>> specific location should explicitly pin the BO before vmapping it.
> 
> Well is the buffer supposed to be scanned out?

No, not by the fbdev helper.

> 
> If yes then the pin location is actually rather important since the
> hardware can only scan out from VRAM.

For relocatable BOs, fbdev uses a shadow buffer that makes all any
relocation transparent to userspace. It flushes the shadow fb into the
BO's memory if there are updates. The code is in
drm_fb_helper_dirty_work(). [1] During the flush operation, the vmap
call now pins the BO to wherever it is. The actual location does not
matter. It's vunmap'ed immediately afterwards.

For dma-buf sharing, the regular procedure of pin + vmap still apply.
This should always move the BO into GTT-managed memory.

Best regards
Thomas

[1]
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/drm_fb_helper.c#n432

> 
> Regards,
> Christian.
> 
>>
>> Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
>> ---
>>   drivers/gpu/drm/radeon/radeon_gem.c | 51 +++++++++++++++++++++++++++--
>>   1 file changed, 49 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/radeon/radeon_gem.c
>> b/drivers/gpu/drm/radeon/radeon_gem.c
>> index d2876ce3bc9e..eaf7fc9a7b07 100644
>> --- a/drivers/gpu/drm/radeon/radeon_gem.c
>> +++ b/drivers/gpu/drm/radeon/radeon_gem.c
>> @@ -226,6 +226,53 @@ static int radeon_gem_handle_lockup(struct
>> radeon_device *rdev, int r)
>>       return r;
>>   }
>>   +static int radeon_gem_object_vmap(struct drm_gem_object *obj,
>> struct dma_buf_map *map)
>> +{
>> +    static const uint32_t any_domain = RADEON_GEM_DOMAIN_VRAM |
>> +                       RADEON_GEM_DOMAIN_GTT |
>> +                       RADEON_GEM_DOMAIN_CPU;
>> +
>> +    struct radeon_bo *bo = gem_to_radeon_bo(obj);
>> +    int ret;
>> +
>> +    ret = radeon_bo_reserve(bo, false);
>> +    if (ret)
>> +        return ret;
>> +
>> +    /* pin buffer at its current location */
>> +    ret = radeon_bo_pin(bo, any_domain, NULL);
>> +    if (ret)
>> +        goto err_radeon_bo_unreserve;
>> +
>> +    ret = drm_gem_ttm_vmap(obj, map);
>> +    if (ret)
>> +        goto err_radeon_bo_unpin;
>> +
>> +    radeon_bo_unreserve(bo);
>> +
>> +    return 0;
>> +
>> +err_radeon_bo_unpin:
>> +    radeon_bo_unpin(bo);
>> +err_radeon_bo_unreserve:
>> +    radeon_bo_unreserve(bo);
>> +    return ret;
>> +}
>> +
>> +static void radeon_gem_object_vunmap(struct drm_gem_object *obj,
>> struct dma_buf_map *map)
>> +{
>> +    struct radeon_bo *bo = gem_to_radeon_bo(obj);
>> +    int ret;
>> +
>> +    ret = radeon_bo_reserve(bo, false);
>> +    if (ret)
>> +        return;
>> +
>> +    drm_gem_ttm_vunmap(obj, map);
>> +    radeon_bo_unpin(bo);
>> +    radeon_bo_unreserve(bo);
>> +}
>> +
>>   static const struct drm_gem_object_funcs radeon_gem_object_funcs = {
>>       .free = radeon_gem_object_free,
>>       .open = radeon_gem_object_open,
>> @@ -234,8 +281,8 @@ static const struct drm_gem_object_funcs
>> radeon_gem_object_funcs = {
>>       .pin = radeon_gem_prime_pin,
>>       .unpin = radeon_gem_prime_unpin,
>>       .get_sg_table = radeon_gem_prime_get_sg_table,
>> -    .vmap = drm_gem_ttm_vmap,
>> -    .vunmap = drm_gem_ttm_vunmap,
>> +    .vmap = radeon_gem_object_vmap,
>> +    .vunmap = radeon_gem_object_vunmap,
>>   };
>>     /*
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 Nürnberg, Germany
(HRB 36809, AG Nürnberg)
Geschäftsführer: Felix Imendörffer


More information about the amd-gfx mailing list