[Mesa-dev] [PATCH 12/12] gallium/radeon/winsyses: decrease max_alloc_size to 1/3 of largest heap

Marek Olšák maraeo at gmail.com
Fri Jul 29 21:42:51 UTC 2016


From: Marek Olšák <marek.olsak at amd.com>

This is controversial, but I don't see a better way out of this.

Tonga has 2 GB of VRAM and 2 GB of GTT. amdgpu is not capable of submitting
an IB referencing 1 GB of VRAM and 1 GB of GTT. The CS ioctl never succeeds
even though it's far below the limits.

Without this, "dEQP-GLES2.functional.color_clear.single_rgb" fails to
submit an IB. With this, dEQP throws a framebuffer-incomplete exception
and kills the process.

IMO, failing the CS ioctl is worse for stability than failing big
allocations.
---
 src/gallium/winsys/amdgpu/drm/amdgpu_bo.c         |  3 +++
 src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c     | 12 +++++++++++-
 src/gallium/winsys/radeon/drm/radeon_drm_bo.c     |  3 +++
 src/gallium/winsys/radeon/drm/radeon_drm_winsys.c | 10 +++++++++-
 4 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c b/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c
index 1805ce6..8e3a87a 100644
--- a/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c
+++ b/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c
@@ -491,6 +491,9 @@ amdgpu_bo_create(struct radeon_winsys *rws,
    struct amdgpu_winsys_bo *bo;
    unsigned usage = 0, pb_cache_bucket;
 
+   if (size > ws->info.max_alloc_size)
+      return NULL;
+
    /* Align size to page size. This is the minimum alignment for normal
     * BOs. Aligning this here helps the cached bufmgr. Especially small BOs,
     * like constant/uniform buffers, can benefit from better and more reuse.
diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c b/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c
index 9a04cbe..44efc2e 100644
--- a/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c
+++ b/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c
@@ -271,7 +271,17 @@ static bool do_winsys_init(struct amdgpu_winsys *ws, int fd)
    ws->info.gart_size = gtt.heap_size;
    ws->info.vram_size = vram.heap_size;
    /* TODO: the kernel reports vram/gart.max_allocation == 251 MB (bug?) */
-   ws->info.max_alloc_size = MAX2(ws->info.vram_size, ws->info.gart_size);
+
+   /* TODO: Drop this limitation once buffers don't have to occupy one
+    * continuous piece of memory. (e.g. split buffers)
+    *
+    * At the moment, the memory manager isn't practically capable of finding
+    * space for a buffer whose size is a half of the heap. Limiting
+    * max_alloc_size to 1/3 of the largest heap still doesn't guarantee
+    * successful command submission, but it's the least we can do.
+    */
+   ws->info.max_alloc_size = MAX2(ws->info.vram_size, ws->info.gart_size) / 3;
+
    /* convert the shader clock from KHz to MHz */
    ws->info.max_shader_clock = ws->amdinfo.max_engine_clk / 1000;
    ws->info.max_se = ws->amdinfo.num_shader_engines;
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c
index 897b536..7e663ee 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c
@@ -731,6 +731,9 @@ radeon_winsys_bo_create(struct radeon_winsys *rws,
     if (size > UINT_MAX)
         return NULL;
 
+    if (size > ws->info.max_alloc_size)
+        return NULL;
+
     /* Align size to page size. This is the minimum alignment for normal
      * BOs. Aligning this here helps the cached bufmgr. Especially small BOs,
      * like constant/uniform buffers, can benefit from better and more reuse.
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c
index 1b32c37..d19d542 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c
@@ -373,7 +373,15 @@ static bool do_winsys_init(struct radeon_drm_winsys *ws)
     ws->info.gart_size = gem_info.gart_size;
     ws->info.vram_size = gem_info.vram_size;
 
-    ws->info.max_alloc_size = MAX2(ws->info.vram_size, ws->info.gart_size);
+    /* TODO: Drop this limitation once buffers don't have to occupy one
+     * continuous piece of memory. (e.g. split buffers)
+     *
+     * At the moment, the memory manager isn't practically capable of finding
+     * space for a buffer whose size is a half of the heap. Limiting
+     * max_alloc_size to 1/3 of the largest heap still doesn't guarantee
+     * successful command submission, but it's the least we can do.
+     */
+    ws->info.max_alloc_size = MAX2(ws->info.vram_size, ws->info.gart_size) / 3;
     if (ws->info.drm_minor < 40)
         ws->info.max_alloc_size = MIN2(ws->info.max_alloc_size, 256*1024*1024);
 
-- 
2.7.4



More information about the mesa-dev mailing list