[Mesa-dev] [PATCH] gallium/pb_bufmgr_cache: limit the size of cache

Marek Olšák maraeo at gmail.com
Thu Aug 21 08:52:54 PDT 2014


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

This should make a machine which is running piglit more responsive at times.
e.g. streaming-texture-leak can easily eat 600 MB because of how fast it
creates new textures.
---
 src/gallium/auxiliary/pipebuffer/pb_bufmgr.h       |  3 ++-
 src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c | 20 ++++++++++++++++++--
 src/gallium/winsys/radeon/drm/radeon_drm_winsys.c  | 12 ++++++++----
 src/gallium/winsys/svga/drm/vmw_screen_pools.c     |  3 ++-
 4 files changed, 30 insertions(+), 8 deletions(-)

diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h b/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h
index d5b0ee2..147ce39 100644
--- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h
+++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h
@@ -163,7 +163,8 @@ struct pb_manager *
 pb_cache_manager_create(struct pb_manager *provider, 
                         unsigned usecs,
                         float size_factor,
-                        unsigned bypass_usage);
+                        unsigned bypass_usage,
+                        uint64_t maximum_cache_size);
 
 
 struct pb_fence_ops;
diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c
index 32a8875..5eb8d06 100644
--- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c
+++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c
@@ -84,6 +84,7 @@ struct pb_cache_manager
    pb_size numDelayed;
    float size_factor;
    unsigned bypass_usage;
+   uint64_t cache_size, max_cache_size;
 };
 
 
@@ -114,6 +115,7 @@ _pb_cache_buffer_destroy(struct pb_cache_buffer *buf)
    LIST_DEL(&buf->head);
    assert(mgr->numDelayed);
    --mgr->numDelayed;
+   mgr->cache_size -= buf->base.size;
    assert(!pipe_is_referenced(&buf->base.reference));
    pb_reference(&buf->buffer, NULL);
    FREE(buf);
@@ -158,11 +160,20 @@ pb_cache_buffer_destroy(struct pb_buffer *_buf)
    assert(!pipe_is_referenced(&buf->base.reference));
    
    _pb_cache_buffer_list_check_free(mgr);
-   
+
+   /* Directly release any buffer that exceeds the limit. */
+   if (mgr->cache_size + buf->base.size > mgr->max_cache_size) {
+      pb_reference(&buf->buffer, NULL);
+      FREE(buf);
+      pipe_mutex_unlock(mgr->mutex);
+      return;
+   }
+
    buf->start = os_time_get();
    buf->end = buf->start + mgr->usecs;
    LIST_ADDTAIL(&buf->head, &mgr->delayed);
    ++mgr->numDelayed;
+   mgr->cache_size += buf->base.size;
    pipe_mutex_unlock(mgr->mutex);
 }
 
@@ -314,6 +325,7 @@ pb_cache_manager_create_buffer(struct pb_manager *_mgr,
    }
    
    if(buf) {
+      mgr->cache_size -= buf->base.size;
       LIST_DEL(&buf->head);
       --mgr->numDelayed;
       pipe_mutex_unlock(mgr->mutex);
@@ -400,12 +412,15 @@ pb_cache_manager_destroy(struct pb_manager *mgr)
  * the requested size as cache hits.
  * @param bypass_usage Bitmask. If (requested usage & bypass_usage) != 0,
  * buffer allocation requests are redirected to the provider.
+ * @param maximum_cache_size  Maximum size of all unused buffers the cache can
+ * hold.
  */
 struct pb_manager *
 pb_cache_manager_create(struct pb_manager *provider, 
                         unsigned usecs,
                         float size_factor,
-                        unsigned bypass_usage)
+                        unsigned bypass_usage,
+                        uint64_t maximum_cache_size)
 {
    struct pb_cache_manager *mgr;
 
@@ -425,6 +440,7 @@ pb_cache_manager_create(struct pb_manager *provider,
    mgr->bypass_usage = bypass_usage;
    LIST_INITHEAD(&mgr->delayed);
    mgr->numDelayed = 0;
+   mgr->max_cache_size = maximum_cache_size;
    pipe_mutex_init(mgr->mutex);
       
    return &mgr->base;
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c
index 820cc90..3b695f9 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c
@@ -671,16 +671,20 @@ radeon_drm_winsys_create(int fd, radeon_screen_create_t screen_create)
     ws->kman = radeon_bomgr_create(ws);
     if (!ws->kman)
         goto fail;
-    ws->cman_vram = pb_cache_manager_create(ws->kman, 1000000, 2.0f, 0);
+    ws->cman_vram = pb_cache_manager_create(ws->kman, 1000000, 2.0f, 0,
+                                            ws->info.vram_size / 8);
     if (!ws->cman_vram)
         goto fail;
-    ws->cman_vram_gtt_wc = pb_cache_manager_create(ws->kman, 1000000, 2.0f, 0);
+    ws->cman_vram_gtt_wc = pb_cache_manager_create(ws->kman, 1000000, 2.0f, 0,
+                                                   ws->info.vram_size / 8);
     if (!ws->cman_vram_gtt_wc)
         goto fail;
-    ws->cman_gtt = pb_cache_manager_create(ws->kman, 1000000, 2.0f, 0);
+    ws->cman_gtt = pb_cache_manager_create(ws->kman, 1000000, 2.0f, 0,
+                                           ws->info.gart_size / 8);
     if (!ws->cman_gtt)
         goto fail;
-    ws->cman_gtt_wc = pb_cache_manager_create(ws->kman, 1000000, 2.0f, 0);
+    ws->cman_gtt_wc = pb_cache_manager_create(ws->kman, 1000000, 2.0f, 0,
+                                              ws->info.gart_size / 8);
     if (!ws->cman_gtt_wc)
         goto fail;
 
diff --git a/src/gallium/winsys/svga/drm/vmw_screen_pools.c b/src/gallium/winsys/svga/drm/vmw_screen_pools.c
index 50d2a81..1815bfa 100644
--- a/src/gallium/winsys/svga/drm/vmw_screen_pools.c
+++ b/src/gallium/winsys/svga/drm/vmw_screen_pools.c
@@ -124,7 +124,8 @@ vmw_mob_pools_init(struct vmw_winsys_screen *vws)
 
    vws->pools.mob_cache = 
       pb_cache_manager_create(vws->pools.gmr, 100000, 2.0f,
-                              VMW_BUFFER_USAGE_SHARED);
+                              VMW_BUFFER_USAGE_SHARED,
+                              64 * 1024 * 1024);
    if (!vws->pools.mob_cache)
       return FALSE;
 
-- 
1.9.1



More information about the mesa-dev mailing list