drm/gem-vram: Do not pin buffer objects for vmap

Pin and vmap are distinct operations. Do not perform a pin as part
of the vmap call. This used to be necessary to keep the fbdev buffer
in place while it is being updated. Fbdev emulation has meanwhile
been fixed to lock the buffer correctly. Same for vunmap.

For refactoring the code, remove the pin calls from the helper's
vmap implementation in drm_gem_vram_vmap() and inline the call to
drm_gem_vram_kmap_locked(). This gives a vmap helper that only
maps the buffer object's memory pages without pinning or locking.
Do a similar refactoring for vunmap.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Tested-by: Dmitry Osipenko <dmitry.osipenko@collabora.com> # virtio-gpu
Acked-by: Zack Rusin <zack.rusin@broadcom.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240227113853.8464-13-tzimmermann@suse.de
This commit is contained in:
Thomas Zimmermann 2024-02-27 11:14:59 +01:00
parent 1709474ba0
commit fe36f1512c

View File

@ -368,54 +368,6 @@ int drm_gem_vram_unpin(struct drm_gem_vram_object *gbo)
}
EXPORT_SYMBOL(drm_gem_vram_unpin);
static int drm_gem_vram_kmap_locked(struct drm_gem_vram_object *gbo,
struct iosys_map *map)
{
int ret;
if (gbo->vmap_use_count > 0)
goto out;
/*
* VRAM helpers unmap the BO only on demand. So the previous
* page mapping might still be around. Only vmap if the there's
* no mapping present.
*/
if (iosys_map_is_null(&gbo->map)) {
ret = ttm_bo_vmap(&gbo->bo, &gbo->map);
if (ret)
return ret;
}
out:
++gbo->vmap_use_count;
*map = gbo->map;
return 0;
}
static void drm_gem_vram_kunmap_locked(struct drm_gem_vram_object *gbo,
struct iosys_map *map)
{
struct drm_device *dev = gbo->bo.base.dev;
if (drm_WARN_ON_ONCE(dev, !gbo->vmap_use_count))
return;
if (drm_WARN_ON_ONCE(dev, !iosys_map_is_equal(&gbo->map, map)))
return; /* BUG: map not mapped from this BO */
if (--gbo->vmap_use_count > 0)
return;
/*
* Permanently mapping and unmapping buffers adds overhead from
* updating the page tables and creates debugging output. Therefore,
* we delay the actual unmap operation until the BO gets evicted
* from memory. See drm_gem_vram_bo_driver_move_notify().
*/
}
/**
* drm_gem_vram_vmap() - Pins and maps a GEM VRAM object into kernel address
* space
@ -438,18 +390,25 @@ int drm_gem_vram_vmap(struct drm_gem_vram_object *gbo, struct iosys_map *map)
dma_resv_assert_held(gbo->bo.base.resv);
ret = drm_gem_vram_pin_locked(gbo, 0);
if (ret)
return ret;
ret = drm_gem_vram_kmap_locked(gbo, map);
if (ret)
goto err_drm_gem_vram_unpin_locked;
if (gbo->vmap_use_count > 0)
goto out;
/*
* VRAM helpers unmap the BO only on demand. So the previous
* page mapping might still be around. Only vmap if the there's
* no mapping present.
*/
if (iosys_map_is_null(&gbo->map)) {
ret = ttm_bo_vmap(&gbo->bo, &gbo->map);
if (ret)
return ret;
}
out:
++gbo->vmap_use_count;
*map = gbo->map;
return 0;
err_drm_gem_vram_unpin_locked:
drm_gem_vram_unpin_locked(gbo);
return ret;
}
EXPORT_SYMBOL(drm_gem_vram_vmap);
@ -464,10 +423,25 @@ EXPORT_SYMBOL(drm_gem_vram_vmap);
void drm_gem_vram_vunmap(struct drm_gem_vram_object *gbo,
struct iosys_map *map)
{
struct drm_device *dev = gbo->bo.base.dev;
dma_resv_assert_held(gbo->bo.base.resv);
drm_gem_vram_kunmap_locked(gbo, map);
drm_gem_vram_unpin_locked(gbo);
if (drm_WARN_ON_ONCE(dev, !gbo->vmap_use_count))
return;
if (drm_WARN_ON_ONCE(dev, !iosys_map_is_equal(&gbo->map, map)))
return; /* BUG: map not mapped from this BO */
if (--gbo->vmap_use_count > 0)
return;
/*
* Permanently mapping and unmapping buffers adds overhead from
* updating the page tables and creates debugging output. Therefore,
* we delay the actual unmap operation until the BO gets evicted
* from memory. See drm_gem_vram_bo_driver_move_notify().
*/
}
EXPORT_SYMBOL(drm_gem_vram_vunmap);