panfrost: protect access to shared bo cache and transient pool
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>
This commit is contained in:
committed by
Boris Brezillon
parent
6b0dc3d530
commit
b2ff2dfc2a
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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]);
|
||||
|
||||
|
||||
@@ -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. */
|
||||
|
||||
Reference in New Issue
Block a user