Commit 245f44e7 authored by Thomas Zimmermann's avatar Thomas Zimmermann

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: default avatarThomas Zimmermann <tzimmermann@suse.de>
Link: https://patchwork.freedesktop.org/patch/msgid/20190923172753.26593-2-tzimmermann@suse.deReviewed-by: default avatarGerd Hoffmann <kraxel@redhat.com>
parent 2ebb6701
...@@ -58,6 +58,7 @@ static void drm_gem_vram_placement(struct drm_gem_vram_object *gbo, ...@@ -58,6 +58,7 @@ static void drm_gem_vram_placement(struct drm_gem_vram_object *gbo,
{ {
unsigned int i; unsigned int i;
unsigned int c = 0; unsigned int c = 0;
u32 invariant_flags = pl_flag & TTM_PL_FLAG_TOPDOWN;
gbo->placement.placement = gbo->placements; gbo->placement.placement = gbo->placements;
gbo->placement.busy_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, ...@@ -65,15 +66,18 @@ static void drm_gem_vram_placement(struct drm_gem_vram_object *gbo,
if (pl_flag & TTM_PL_FLAG_VRAM) if (pl_flag & TTM_PL_FLAG_VRAM)
gbo->placements[c++].flags = TTM_PL_FLAG_WC | gbo->placements[c++].flags = TTM_PL_FLAG_WC |
TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_UNCACHED |
TTM_PL_FLAG_VRAM; TTM_PL_FLAG_VRAM |
invariant_flags;
if (pl_flag & TTM_PL_FLAG_SYSTEM) if (pl_flag & TTM_PL_FLAG_SYSTEM)
gbo->placements[c++].flags = TTM_PL_MASK_CACHING | gbo->placements[c++].flags = TTM_PL_MASK_CACHING |
TTM_PL_FLAG_SYSTEM; TTM_PL_FLAG_SYSTEM |
invariant_flags;
if (!c) if (!c)
gbo->placements[c++].flags = TTM_PL_MASK_CACHING | 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_placement = c;
gbo->placement.num_busy_placement = c; gbo->placement.num_busy_placement = c;
...@@ -238,6 +242,14 @@ static int drm_gem_vram_pin_locked(struct drm_gem_vram_object *gbo, ...@@ -238,6 +242,14 @@ static int drm_gem_vram_pin_locked(struct drm_gem_vram_object *gbo,
* the buffer is pinned at its current location (video RAM or system * the buffer is pinned at its current location (video RAM or system
* memory). * 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: * Returns:
* 0 on success, or * 0 on success, or
* a negative error code otherwise. * a negative error code otherwise.
......
...@@ -19,6 +19,7 @@ struct vm_area_struct; ...@@ -19,6 +19,7 @@ struct vm_area_struct;
#define DRM_GEM_VRAM_PL_FLAG_VRAM TTM_PL_FLAG_VRAM #define DRM_GEM_VRAM_PL_FLAG_VRAM TTM_PL_FLAG_VRAM
#define DRM_GEM_VRAM_PL_FLAG_SYSTEM TTM_PL_FLAG_SYSTEM #define DRM_GEM_VRAM_PL_FLAG_SYSTEM TTM_PL_FLAG_SYSTEM
#define DRM_GEM_VRAM_PL_FLAG_TOPDOWN TTM_PL_FLAG_TOPDOWN
/* /*
* Buffer-object helpers * Buffer-object helpers
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment