From 175549e0e988d10f8277c30ae4e6b6d5fea702a4 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Mon, 1 Jan 2018 22:47:36 +0100 Subject: pb_cache: let drivers choose the number of buckets Reviewed-by: Samuel Pitoiset --- src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c | 2 +- src/gallium/auxiliary/pipebuffer/pb_cache.c | 23 ++++++++++++++++++---- src/gallium/auxiliary/pipebuffer/pb_cache.h | 6 ++++-- src/gallium/winsys/amdgpu/drm/amdgpu_bo.c | 1 - src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c | 3 ++- src/gallium/winsys/radeon/drm/radeon_drm_bo.c | 1 - src/gallium/winsys/radeon/drm/radeon_drm_winsys.c | 3 ++- 7 files changed, 28 insertions(+), 11 deletions(-) diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c index 24831f60948..4e70048cd83 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c @@ -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); diff --git a/src/gallium/auxiliary/pipebuffer/pb_cache.c b/src/gallium/auxiliary/pipebuffer/pb_cache.c index dd479ae7719..0aaedbfae4c 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_cache.c +++ b/src/gallium/auxiliary/pipebuffer/pb_cache.c @@ -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; } diff --git a/src/gallium/auxiliary/pipebuffer/pb_cache.h b/src/gallium/auxiliary/pipebuffer/pb_cache.h index d082eca8b5d..904095c38b5 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_cache.h +++ b/src/gallium/auxiliary/pipebuffer/pb_cache.h @@ -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)); diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c b/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c index 4b12735bac0..92c314ecf0a 100644 --- a/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c +++ b/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c @@ -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*) diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c b/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c index ab91faf7cbc..707ebf92730 100644 --- a/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c +++ b/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c @@ -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); diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c index fc95a98620b..4be6f4002ff 100644 --- a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c +++ b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c @@ -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)); diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c index 10f2ecc900f..dee4366ac50 100644 --- a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c +++ b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c @@ -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); -- cgit v1.2.3