summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/drm_gem_vram_helper.c
diff options
context:
space:
mode:
authorThomas Zimmermann <tzimmermann@suse.de>2019-09-23 19:27:42 +0200
committerThomas Zimmermann <tzimmermann@suse.de>2019-09-27 09:48:53 +0200
commit245f44e77101df44e1074c765732b5613579179d (patch)
tree693f95401b38e089642993b9229fb6931b82fc68 /drivers/gpu/drm/drm_gem_vram_helper.c
parent2ebb6701654e0d625eac6c32832d72f8e875c01a (diff)
drm/vram: Support top-down placement flag
Pinning lots of small buffer objects, such as cursors or sprites, to video memory can lead to fragmentation, which is a problem for devices with only a small amount of memory. As a result, framebuffer images might not get pinned, even though there's enough space available overall. The flag DRM_GEM_VRAM_PL_FLAG_TOPDOWN marks buffer objects to be pinned at the high end of video memory. This leaves contiguous space available at the memory's low end. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Link: https://patchwork.freedesktop.org/patch/msgid/20190923172753.26593-2-tzimmermann@suse.de Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/drm_gem_vram_helper.c')
-rw-r--r--drivers/gpu/drm/drm_gem_vram_helper.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/drivers/gpu/drm/drm_gem_vram_helper.c b/drivers/gpu/drm/drm_gem_vram_helper.c
index 49588de88959..dc7942981f4a 100644
--- a/drivers/gpu/drm/drm_gem_vram_helper.c
+++ b/drivers/gpu/drm/drm_gem_vram_helper.c
@@ -58,6 +58,7 @@ static void drm_gem_vram_placement(struct drm_gem_vram_object *gbo,
{
unsigned int i;
unsigned int c = 0;
+ u32 invariant_flags = pl_flag & TTM_PL_FLAG_TOPDOWN;
gbo->placement.placement = gbo->placements;
gbo->placement.busy_placement = gbo->placements;
@@ -65,15 +66,18 @@ static void drm_gem_vram_placement(struct drm_gem_vram_object *gbo,
if (pl_flag & TTM_PL_FLAG_VRAM)
gbo->placements[c++].flags = TTM_PL_FLAG_WC |
TTM_PL_FLAG_UNCACHED |
- TTM_PL_FLAG_VRAM;
+ TTM_PL_FLAG_VRAM |
+ invariant_flags;
if (pl_flag & TTM_PL_FLAG_SYSTEM)
gbo->placements[c++].flags = TTM_PL_MASK_CACHING |
- TTM_PL_FLAG_SYSTEM;
+ TTM_PL_FLAG_SYSTEM |
+ invariant_flags;
if (!c)
gbo->placements[c++].flags = TTM_PL_MASK_CACHING |
- TTM_PL_FLAG_SYSTEM;
+ TTM_PL_FLAG_SYSTEM |
+ invariant_flags;
gbo->placement.num_placement = c;
gbo->placement.num_busy_placement = c;
@@ -238,6 +242,14 @@ out:
* the buffer is pinned at its current location (video RAM or system
* memory).
*
+ * Small buffer objects, such as cursor images, can lead to memory
+ * fragmentation if they are pinned in the middle of video RAM. This
+ * is especially a problem on devices with only a small amount of
+ * video RAM. Fragmentation can prevent the primary framebuffer from
+ * fitting in, even though there's enough memory overall. The modifier
+ * DRM_GEM_VRAM_PL_FLAG_TOPDOWN marks the buffer object to be pinned
+ * at the high end of the memory region to avoid fragmentation.
+ *
* Returns:
* 0 on success, or
* a negative error code otherwise.