pb_cache: let drivers choose the number of buckets
authorMarek Olšák <marek.olsak@amd.com>
Mon, 1 Jan 2018 21:47:36 +0000 (22:47 +0100)
committerMarek Olšák <marek.olsak@amd.com>
Sat, 27 Jan 2018 01:09:09 +0000 (02:09 +0100)
Reviewed-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c
src/gallium/auxiliary/pipebuffer/pb_cache.c
src/gallium/auxiliary/pipebuffer/pb_cache.h
src/gallium/winsys/amdgpu/drm/amdgpu_bo.c
src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c
src/gallium/winsys/radeon/drm/radeon_drm_bo.c
src/gallium/winsys/radeon/drm/radeon_drm_winsys.c

index 24831f60948cd714948fdcf5e8a7d3f72e9d7f61..4e70048cd8348c02cfe5090225cc8b3470a608e4 100644 (file)
@@ -304,7 +304,7 @@ pb_cache_manager_create(struct pb_manager *provider,
    mgr->base.create_buffer = pb_cache_manager_create_buffer;
    mgr->base.flush = pb_cache_manager_flush;
    mgr->provider = provider;
-   pb_cache_init(&mgr->cache, usecs, size_factor, bypass_usage,
+   pb_cache_init(&mgr->cache, 1, usecs, size_factor, bypass_usage,
                  maximum_cache_size,
                  _pb_cache_buffer_destroy,
                  pb_cache_can_reclaim_buffer);
index dd479ae7719c86d6723943bf075cd8573ad78010..0aaedbfae4ccbb58f08cd26b8e29acccd3320ad6 100644 (file)
@@ -92,7 +92,7 @@ pb_cache_add_buffer(struct pb_cache_entry *entry)
 
    int64_t current_time = os_time_get();
 
-   for (i = 0; i < ARRAY_SIZE(mgr->buckets); i++)
+   for (i = 0; i < mgr->num_heaps; i++)
       release_expired_buffers_locked(&mgr->buckets[i], current_time);
 
    /* Directly release any buffer that exceeds the limit. */
@@ -153,6 +153,8 @@ pb_cache_reclaim_buffer(struct pb_cache *mgr, pb_size size,
    struct list_head *cur, *next;
    int64_t now;
    int ret = 0;
+
+   assert(bucket_index < mgr->num_heaps);
    struct list_head *cache = &mgr->buckets[bucket_index];
 
    mtx_lock(&mgr->mutex);
@@ -229,7 +231,7 @@ pb_cache_release_all_buffers(struct pb_cache *mgr)
    unsigned i;
 
    mtx_lock(&mgr->mutex);
-   for (i = 0; i < ARRAY_SIZE(mgr->buckets); i++) {
+   for (i = 0; i < mgr->num_heaps; i++) {
       struct list_head *cache = &mgr->buckets[i];
 
       curr = cache->next;
@@ -248,6 +250,8 @@ void
 pb_cache_init_entry(struct pb_cache *mgr, struct pb_cache_entry *entry,
                     struct pb_buffer *buf, unsigned bucket_index)
 {
+   assert(bucket_index < mgr->num_heaps);
+
    memset(entry, 0, sizeof(*entry));
    entry->buffer = buf;
    entry->mgr = mgr;
@@ -258,6 +262,9 @@ pb_cache_init_entry(struct pb_cache *mgr, struct pb_cache_entry *entry,
  * Initialize a caching buffer manager.
  *
  * @param mgr     The cache buffer manager
+ * @param num_heaps  Number of separate caches/buckets indexed by bucket_index
+ *                   for faster buffer matching (alternative to slower
+ *                   "usage"-based matching).
  * @param usecs   Unused buffers may be released from the cache after this
  *                time
  * @param size_factor  Declare buffers that are size_factor times bigger than
@@ -270,19 +277,25 @@ pb_cache_init_entry(struct pb_cache *mgr, struct pb_cache_entry *entry,
  * @param can_reclaim     Whether a buffer can be reclaimed (e.g. is not busy)
  */
 void
-pb_cache_init(struct pb_cache *mgr, uint usecs, float size_factor,
+pb_cache_init(struct pb_cache *mgr, uint num_heaps,
+              uint usecs, float size_factor,
               unsigned bypass_usage, uint64_t maximum_cache_size,
               void (*destroy_buffer)(struct pb_buffer *buf),
               bool (*can_reclaim)(struct pb_buffer *buf))
 {
    unsigned i;
 
-   for (i = 0; i < ARRAY_SIZE(mgr->buckets); i++)
+   mgr->buckets = CALLOC(num_heaps, sizeof(struct list_head));
+   if (!mgr->buckets)
+      return;
+
+   for (i = 0; i < num_heaps; i++)
       LIST_INITHEAD(&mgr->buckets[i]);
 
    (void) mtx_init(&mgr->mutex, mtx_plain);
    mgr->cache_size = 0;
    mgr->max_cache_size = maximum_cache_size;
+   mgr->num_heaps = num_heaps;
    mgr->usecs = usecs;
    mgr->num_buffers = 0;
    mgr->bypass_usage = bypass_usage;
@@ -299,4 +312,6 @@ pb_cache_deinit(struct pb_cache *mgr)
 {
    pb_cache_release_all_buffers(mgr);
    mtx_destroy(&mgr->mutex);
+   FREE(mgr->buckets);
+   mgr->buckets = NULL;
 }
index d082eca8b5d1177b7035c42bcd2cc50ed176883a..904095c38b5a77c7127cb01d8e8b6aaf2d6f8bd1 100644 (file)
@@ -50,11 +50,12 @@ struct pb_cache
    /* The cache is divided into buckets for minimizing cache misses.
     * The driver controls which buffer goes into which bucket.
     */
-   struct list_head buckets[4];
+   struct list_head *buckets;
 
    mtx_t mutex;
    uint64_t cache_size;
    uint64_t max_cache_size;
+   unsigned num_heaps;
    unsigned usecs;
    unsigned num_buffers;
    unsigned bypass_usage;
@@ -71,7 +72,8 @@ struct pb_buffer *pb_cache_reclaim_buffer(struct pb_cache *mgr, pb_size size,
 void pb_cache_release_all_buffers(struct pb_cache *mgr);
 void pb_cache_init_entry(struct pb_cache *mgr, struct pb_cache_entry *entry,
                          struct pb_buffer *buf, unsigned bucket_index);
-void pb_cache_init(struct pb_cache *mgr, uint usecs, float size_factor,
+void pb_cache_init(struct pb_cache *mgr, uint num_heaps,
+                   uint usecs, float size_factor,
                    unsigned bypass_usage, uint64_t maximum_cache_size,
                    void (*destroy_buffer)(struct pb_buffer *buf),
                    bool (*can_reclaim)(struct pb_buffer *buf));
index 4b12735bac05600a1ec6838378819f6629f1ddf6..92c314ecf0a43be0bdfb8726267b3107a5354424 100644 (file)
@@ -1226,7 +1226,6 @@ no_slab:
        usage = 1 << heap; /* Only set one usage bit for each heap. */
 
        pb_cache_bucket = radeon_get_pb_cache_bucket_index(heap);
-       assert(pb_cache_bucket < ARRAY_SIZE(ws->bo_cache.buckets));
 
        /* Get a buffer from the cache. */
        bo = (struct amdgpu_winsys_bo*)
index ab91faf7cbce7df4896603440f9d1845c1d0e658..707ebf927305b79bc71b1341d8b98ca817a307d0 100644 (file)
@@ -285,7 +285,8 @@ amdgpu_winsys_create(int fd, const struct pipe_screen_config *config,
       goto fail_alloc;
 
    /* Create managers. */
-   pb_cache_init(&ws->bo_cache, 500000, ws->check_vm ? 1.0f : 2.0f, 0,
+   pb_cache_init(&ws->bo_cache, 4,
+                 500000, ws->check_vm ? 1.0f : 2.0f, 0,
                  (ws->info.vram_size + ws->info.gart_size) / 8,
                  amdgpu_bo_destroy, amdgpu_bo_can_reclaim);
 
index fc95a98620b12a868216590693c18ab78b093375..4be6f4002ff4c528a7c52de1154d97eeef2cba85 100644 (file)
@@ -985,7 +985,6 @@ no_slab:
         usage = 1 << heap; /* Only set one usage bit for each heap. */
 
         pb_cache_bucket = radeon_get_pb_cache_bucket_index(heap);
-        assert(pb_cache_bucket < ARRAY_SIZE(ws->bo_cache.buckets));
 
         bo = radeon_bo(pb_cache_reclaim_buffer(&ws->bo_cache, size, alignment,
                                                usage, pb_cache_bucket));
index 10f2ecc900fa1082d9594c5f92f61d0cd8c77483..dee4366ac503a8be8cc8db669a23ce70992e5427 100644 (file)
@@ -763,7 +763,8 @@ radeon_drm_winsys_create(int fd, const struct pipe_screen_config *config,
     if (!do_winsys_init(ws))
         goto fail1;
 
-    pb_cache_init(&ws->bo_cache, 500000, ws->check_vm ? 1.0f : 2.0f, 0,
+    pb_cache_init(&ws->bo_cache, 4,
+                  500000, ws->check_vm ? 1.0f : 2.0f, 0,
                   MIN2(ws->info.vram_size, ws->info.gart_size),
                   radeon_bo_destroy,
                   radeon_bo_can_reclaim);