Mesa (master): panfrost: Add BO cache data structure

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon Jul 15 23:14:22 UTC 2019


Module: Mesa
Branch: master
Commit: 270733fe6af0a726797259f6205c2e6740351e02
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=270733fe6af0a726797259f6205c2e6740351e02

Author: Alyssa Rosenzweig <alyssa.rosenzweig at collabora.com>
Date:   Mon Jul 15 08:36:19 2019 -0700

panfrost: Add BO cache data structure

Linked list of panfrost_bo* nested inside an array of buckets.

Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig at collabora.com>

---

 src/gallium/drivers/panfrost/pan_allocate.h |  5 +++++
 src/gallium/drivers/panfrost/pan_screen.c   |  3 +++
 src/gallium/drivers/panfrost/pan_screen.h   | 16 ++++++++++++++++
 3 files changed, 24 insertions(+)

diff --git a/src/gallium/drivers/panfrost/pan_allocate.h b/src/gallium/drivers/panfrost/pan_allocate.h
index 43f69b4aceb..8d925ee38a4 100644
--- a/src/gallium/drivers/panfrost/pan_allocate.h
+++ b/src/gallium/drivers/panfrost/pan_allocate.h
@@ -31,6 +31,8 @@
 
 #include <panfrost-misc.h>
 
+#include "util/list.h"
+
 struct panfrost_context;
 
 /* Represents a fat pointer for GPU-mapped memory, returned from the transient
@@ -42,6 +44,9 @@ struct panfrost_transfer {
 };
 
 struct panfrost_bo {
+        /* Must be first for casting */
+        struct list_head link;
+
         struct pipe_reference reference;
 
         /* Mapping for the entire object (all levels) */
diff --git a/src/gallium/drivers/panfrost/pan_screen.c b/src/gallium/drivers/panfrost/pan_screen.c
index 48ffde0d7b1..43a26856f9b 100644
--- a/src/gallium/drivers/panfrost/pan_screen.c
+++ b/src/gallium/drivers/panfrost/pan_screen.c
@@ -536,6 +536,9 @@ panfrost_create_screen(int fd, struct renderonly *ro)
 
         util_dynarray_init(&screen->transient_bo, screen);
 
+        for (unsigned i = 0; i < ARRAY_SIZE(screen->bo_cache); ++i)
+                list_inithead(&screen->bo_cache[i]);
+
         if (pan_debug & PAN_DBG_TRACE)
                 pandecode_initialize();
 
diff --git a/src/gallium/drivers/panfrost/pan_screen.h b/src/gallium/drivers/panfrost/pan_screen.h
index 18866db049e..3ea624c8855 100644
--- a/src/gallium/drivers/panfrost/pan_screen.h
+++ b/src/gallium/drivers/panfrost/pan_screen.h
@@ -81,6 +81,16 @@ struct panfrost_screen;
 
 #define MAX_TRANSIENT_SLABS (1024*1024 / TRANSIENT_SLAB_PAGES)
 
+/* How many power-of-two levels in the BO cache do we want? 2^12
+ * minimum chosen as it is the page size that all allocations are
+ * rounded to */
+
+#define MIN_BO_CACHE_BUCKET (12) /* 2^12 = 4KB */
+#define MAX_BO_CACHE_BUCKET (22) /* 2^22 = 4MB */
+
+/* Fencepost problem, hence the off-by-one */
+#define NR_BO_CACHE_BUCKETS (MAX_BO_CACHE_BUCKET - MIN_BO_CACHE_BUCKET + 1)
+
 struct panfrost_screen {
         struct pipe_screen base;
         int fd;
@@ -97,6 +107,12 @@ struct panfrost_screen {
         /* Set of free transient BOs */
         BITSET_DECLARE(free_transient, MAX_TRANSIENT_SLABS);
 
+        /* The BO cache is a set of buckets with power-of-two sizes ranging
+         * from 2^12 (4096, the page size) to 2^(12 + MAX_BO_CACHE_BUCKETS).
+         * Each bucket is a linked list of free panfrost_bo objects. */
+
+        struct list_head bo_cache[NR_BO_CACHE_BUCKETS];
+
         /* While we're busy building up the job for frame N, the GPU is
          * still busy executing frame N-1. So hold a reference to
          * yesterjob */




More information about the mesa-commit mailing list