panfrost: protect access to shared bo cache and transient pool
authorRohan Garg <rohan.garg@collabora.com>
Fri, 30 Aug 2019 16:00:13 +0000 (18:00 +0200)
committerBoris Brezillon <boris.brezillon@collabora.com>
Fri, 30 Aug 2019 20:10:49 +0000 (22:10 +0200)
Both the BO cache and the transient pool are shared across
context's. Protect access to these with mutexes.

Signed-off-by: Rohan Garg <rohan.garg@collabora.com>
Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
src/gallium/drivers/panfrost/pan_allocate.c
src/gallium/drivers/panfrost/pan_bo_cache.c
src/gallium/drivers/panfrost/pan_job.c
src/gallium/drivers/panfrost/pan_screen.c
src/gallium/drivers/panfrost/pan_screen.h

index f549c864c70b7e170f1863e6b5819bc6838f5f3f..fb8b18fe718bc8b8a57be01eb6becafaf25d0241 100644 (file)
@@ -74,6 +74,7 @@ panfrost_allocate_transient(struct panfrost_context *ctx, size_t sz)
         unsigned offset = 0;
         bool update_offset = false;
 
+        pthread_mutex_lock(&screen->transient_lock);
         bool has_current = batch->transient_indices.size;
         bool fits_in_current = (batch->transient_offset + sz) < TRANSIENT_SLAB_SIZE;
 
@@ -131,6 +132,7 @@ panfrost_allocate_transient(struct panfrost_context *ctx, size_t sz)
 
         if (update_offset)
                 batch->transient_offset = offset + sz;
+        pthread_mutex_unlock(&screen->transient_lock);
 
         return ret;
 
index 9dd6b694b725c08ddfd4f203dd524919ac310e50..f2f49437a89fa49fec3abba02edb27b7766b934a 100644 (file)
@@ -24,6 +24,7 @@
  *   Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
  */
 #include <xf86drm.h>
+#include <pthread.h>
 #include "drm-uapi/panfrost_drm.h"
 
 #include "pan_screen.h"
@@ -84,7 +85,9 @@ panfrost_bo_cache_fetch(
                 struct panfrost_screen *screen,
                 size_t size, uint32_t flags)
 {
+        pthread_mutex_lock(&screen->bo_cache_lock);
         struct list_head *bucket = pan_bucket(screen, size);
+        struct panfrost_bo *bo = NULL;
 
         /* Iterate the bucket looking for something suitable */
         list_for_each_entry_safe(struct panfrost_bo, entry, bucket, link) {
@@ -106,12 +109,13 @@ panfrost_bo_cache_fetch(
                                 continue;
                         }
                         /* Let's go! */
-                        return entry;
+                        bo = entry;
+                        break;
                 }
         }
+        pthread_mutex_unlock(&screen->bo_cache_lock);
 
-        /* We didn't find anything */
-        return NULL;
+        return bo;
 }
 
 /* Tries to add a BO to the cache. Returns if it was
@@ -122,6 +126,7 @@ panfrost_bo_cache_put(
                 struct panfrost_screen *screen,
                 struct panfrost_bo *bo)
 {
+        pthread_mutex_lock(&screen->bo_cache_lock);
         struct list_head *bucket = pan_bucket(screen, bo->size);
         struct drm_panfrost_madvise madv;
 
@@ -133,6 +138,7 @@ panfrost_bo_cache_put(
 
         /* Add us to the bucket */
         list_addtail(&bo->link, bucket);
+        pthread_mutex_unlock(&screen->bo_cache_lock);
 
         return true;
 }
@@ -147,6 +153,7 @@ void
 panfrost_bo_cache_evict_all(
                 struct panfrost_screen *screen)
 {
+        pthread_mutex_lock(&screen->bo_cache_lock);
         for (unsigned i = 0; i < ARRAY_SIZE(screen->bo_cache); ++i) {
                 struct list_head *bucket = &screen->bo_cache[i];
 
@@ -155,7 +162,6 @@ panfrost_bo_cache_evict_all(
                         panfrost_drm_release_bo(screen, entry, false);
                 }
         }
-
-        return;
+        pthread_mutex_unlock(&screen->bo_cache_lock);
 }
 
index f5bbd04b913fc4277c7c1091db51df5a2fdcb83b..f7ff57c4331ad6600f8cba47d5a2f174e3555d55 100644 (file)
@@ -67,10 +67,12 @@ panfrost_free_job(struct panfrost_context *ctx, struct panfrost_job *job)
         /* Free up the transient BOs we're sitting on */
         struct panfrost_screen *screen = pan_screen(ctx->base.screen);
 
+        pthread_mutex_lock(&screen->transient_lock);
         util_dynarray_foreach(&job->transient_indices, unsigned, index) {
                 /* Mark it free */
                 BITSET_SET(screen->free_transient, *index);
         }
+        pthread_mutex_unlock(&screen->transient_lock);
 
         /* Unreference the polygon list */
         panfrost_bo_unreference(ctx->base.screen, job->polygon_list);
index 5c288f52bbd5816c286104a4a7079a7b1bae3555..bd826808fd6f211acdd120499b243caaef9841d4 100644 (file)
@@ -542,6 +542,8 @@ panfrost_destroy_screen(struct pipe_screen *pscreen)
 {
         struct panfrost_screen *screen = pan_screen(pscreen);
         panfrost_bo_cache_evict_all(screen);
+        pthread_mutex_destroy(&screen->bo_cache_lock);
+        pthread_mutex_destroy(&screen->transient_lock);
         drmFreeVersion(screen->kernel_version);
         ralloc_free(screen);
 }
@@ -639,8 +641,10 @@ panfrost_create_screen(int fd, struct renderonly *ro)
                 return NULL;
         }
 
+        pthread_mutex_init(&screen->transient_lock, NULL);
         util_dynarray_init(&screen->transient_bo, screen);
 
+        pthread_mutex_init(&screen->bo_cache_lock, NULL);
         for (unsigned i = 0; i < ARRAY_SIZE(screen->bo_cache); ++i)
                 list_inithead(&screen->bo_cache[i]);
 
index 0a8da3362fb75922272ef043a7040e89e4ec39c3..d8ea55912b4e39421268999fd2a867a1767d8a46 100644 (file)
@@ -104,6 +104,8 @@ struct panfrost_screen {
 
         struct renderonly *ro;
 
+        pthread_mutex_t transient_lock;
+
         /* Transient memory management is based on borrowing fixed-size slabs
          * off the screen (loaning them out to the batch). Dynamic array
          * container of panfrost_bo */
@@ -113,6 +115,8 @@ struct panfrost_screen {
         /* Set of free transient BOs */
         BITSET_DECLARE(free_transient, MAX_TRANSIENT_SLABS);
 
+        pthread_mutex_t bo_cache_lock;
+
         /* 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. */