[Mesa-dev] [PATCH 1/7] winsys/amdgpu: always reclaim/release slabs if there is not enough memory

Marek Olšák maraeo at gmail.com
Fri Nov 23 23:40:46 UTC 2018


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

---
 src/gallium/winsys/amdgpu/drm/amdgpu_bo.c | 20 +++++++++++++-------
 1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c b/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c
index 3ee38b8a79f..49de30bb57c 100644
--- a/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c
+++ b/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c
@@ -211,20 +211,26 @@ static void amdgpu_bo_destroy_or_cache(struct pb_buffer *_buf)
    struct amdgpu_winsys_bo *bo = amdgpu_winsys_bo(_buf);
 
    assert(bo->bo); /* slab buffers have a separate vtbl */
 
    if (bo->u.real.use_reusable_pool)
       pb_cache_add_buffer(&bo->u.real.cache_entry);
    else
       amdgpu_bo_destroy(_buf);
 }
 
+static void amdgpu_clean_up_buffer_managers(struct amdgpu_winsys *ws)
+{
+   pb_slabs_reclaim(&ws->bo_slabs);
+   pb_cache_release_all_buffers(&ws->bo_cache);
+}
+
 static void *amdgpu_bo_map(struct pb_buffer *buf,
                            struct radeon_cmdbuf *rcs,
                            enum pipe_transfer_usage usage)
 {
    struct amdgpu_winsys_bo *bo = (struct amdgpu_winsys_bo*)buf;
    struct amdgpu_winsys_bo *real;
    struct amdgpu_cs *cs = (struct amdgpu_cs*)rcs;
    int r;
    void *cpu = NULL;
    uint64_t offset = 0;
@@ -318,22 +324,22 @@ static void *amdgpu_bo_map(struct pb_buffer *buf,
 
    if (bo->bo) {
       real = bo;
    } else {
       real = bo->u.slab.real;
       offset = bo->va - real->va;
    }
 
    r = amdgpu_bo_cpu_map(real->bo, &cpu);
    if (r) {
-      /* Clear the cache and try again. */
-      pb_cache_release_all_buffers(&real->ws->bo_cache);
+      /* Clean up buffer managers and try again. */
+      amdgpu_clean_up_buffer_managers(real->ws);
       r = amdgpu_bo_cpu_map(real->bo, &cpu);
       if (r)
          return NULL;
    }
 
    if (p_atomic_inc_return(&real->u.real.map_count) == 1) {
       if (real->initial_domain & RADEON_DOMAIN_VRAM)
          real->ws->mapped_vram += real->base.size;
       else if (real->initial_domain & RADEON_DOMAIN_GTT)
          real->ws->mapped_gtt += real->base.size;
@@ -1198,22 +1204,22 @@ amdgpu_bo_create(struct radeon_winsys *rws,
        size <= (1 << AMDGPU_SLAB_MAX_SIZE_LOG2) &&
        alignment <= MAX2(1 << AMDGPU_SLAB_MIN_SIZE_LOG2, util_next_power_of_two(size))) {
       struct pb_slab_entry *entry;
       int heap = radeon_get_heap_index(domain, flags);
 
       if (heap < 0 || heap >= RADEON_MAX_SLAB_HEAPS)
          goto no_slab;
 
       entry = pb_slab_alloc(&ws->bo_slabs, size, heap);
       if (!entry) {
-         /* Clear the cache and try again. */
-         pb_cache_release_all_buffers(&ws->bo_cache);
+         /* Clean up buffer managers and try again. */
+         amdgpu_clean_up_buffer_managers(ws);
 
          entry = pb_slab_alloc(&ws->bo_slabs, size, heap);
       }
       if (!entry)
          return NULL;
 
       bo = NULL;
       bo = container_of(entry, bo, u.slab.entry);
 
       pipe_reference_init(&bo->base.reference, 1);
@@ -1247,23 +1253,23 @@ no_slab:
        /* Get a buffer from the cache. */
        bo = (struct amdgpu_winsys_bo*)
             pb_cache_reclaim_buffer(&ws->bo_cache, size, alignment, 0, heap);
        if (bo)
           return &bo->base;
    }
 
    /* Create a new one. */
    bo = amdgpu_create_bo(ws, size, alignment, domain, flags, heap);
    if (!bo) {
-      /* Clear the cache and try again. */
-      pb_slabs_reclaim(&ws->bo_slabs);
-      pb_cache_release_all_buffers(&ws->bo_cache);
+      /* Clean up buffer managers and try again. */
+      amdgpu_clean_up_buffer_managers(ws);
+
       bo = amdgpu_create_bo(ws, size, alignment, domain, flags, heap);
       if (!bo)
          return NULL;
    }
 
    bo->u.real.use_reusable_pool = use_reusable_pool;
    return &bo->base;
 }
 
 static struct pb_buffer *amdgpu_bo_from_handle(struct radeon_winsys *rws,
-- 
2.17.1



More information about the mesa-dev mailing list