From 28328298ca94344538a0d7f41350810f086900ee Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Fri, 17 Aug 2018 15:58:17 -0400 Subject: [PATCH 1/1] freedreno: move ring_cache behind fd_bo_del() So that it isn't bypassing normal refcnt'ing. Signed-off-by: Rob Clark --- freedreno/freedreno_bo.c | 39 ++++++++++++++++++++++++++++++++------- freedreno/freedreno_device.c | 1 + freedreno/freedreno_priv.h | 11 ++++++++++- freedreno/msm/msm_device.c | 3 --- freedreno/msm/msm_ringbuffer.c | 39 ++------------------------------------- 5 files changed, 45 insertions(+), 48 deletions(-) diff --git a/freedreno/freedreno_bo.c b/freedreno/freedreno_bo.c index 34c285fb..6f4e27b3 100644 --- a/freedreno/freedreno_bo.c +++ b/freedreno/freedreno_bo.c @@ -78,14 +78,15 @@ static struct fd_bo * bo_from_handle(struct fd_device *dev, return bo; } -struct fd_bo * -fd_bo_new(struct fd_device *dev, uint32_t size, uint32_t flags) +static struct fd_bo * +bo_new(struct fd_device *dev, uint32_t size, uint32_t flags, + struct fd_bo_cache *cache) { struct fd_bo *bo = NULL; uint32_t handle; int ret; - bo = fd_bo_cache_alloc(&dev->bo_cache, &size, flags); + bo = fd_bo_cache_alloc(cache, &size, flags); if (bo) return bo; @@ -95,7 +96,6 @@ fd_bo_new(struct fd_device *dev, uint32_t size, uint32_t flags) pthread_mutex_lock(&table_lock); bo = bo_from_handle(dev, size, handle); - bo->bo_reuse = TRUE; pthread_mutex_unlock(&table_lock); VG_BO_ALLOC(bo); @@ -104,6 +104,29 @@ fd_bo_new(struct fd_device *dev, uint32_t size, uint32_t flags) } struct fd_bo * +fd_bo_new(struct fd_device *dev, uint32_t size, uint32_t flags) +{ + struct fd_bo *bo = bo_new(dev, size, flags, &dev->bo_cache); + if (bo) + bo->bo_reuse = BO_CACHE; + return bo; +} + +/* internal function to allocate bo's that use the ringbuffer cache + * instead of the normal bo_cache. The purpose is, because cmdstream + * bo's get vmap'd on the kernel side, and that is expensive, we want + * to re-use cmdstream bo's for cmdstream and not unrelated purposes. + */ +drm_private struct fd_bo * +fd_bo_new_ring(struct fd_device *dev, uint32_t size, uint32_t flags) +{ + struct fd_bo *bo = bo_new(dev, size, flags, &dev->ring_cache); + if (bo) + bo->bo_reuse = RING_CACHE; + return bo; +} + +struct fd_bo * fd_bo_from_handle(struct fd_device *dev, uint32_t handle, uint32_t size) { struct fd_bo *bo = NULL; @@ -216,7 +239,9 @@ void fd_bo_del(struct fd_bo *bo) pthread_mutex_lock(&table_lock); - if (bo->bo_reuse && (fd_bo_cache_free(&dev->bo_cache, bo) == 0)) + if ((bo->bo_reuse == BO_CACHE) && (fd_bo_cache_free(&dev->bo_cache, bo) == 0)) + goto out; + if ((bo->bo_reuse == RING_CACHE) && (fd_bo_cache_free(&dev->ring_cache, bo) == 0)) goto out; bo_del(bo); @@ -266,7 +291,7 @@ int fd_bo_get_name(struct fd_bo *bo, uint32_t *name) pthread_mutex_lock(&table_lock); set_name(bo, req.name); pthread_mutex_unlock(&table_lock); - bo->bo_reuse = FALSE; + bo->bo_reuse = NO_CACHE; } *name = bo->name; @@ -290,7 +315,7 @@ int fd_bo_dmabuf(struct fd_bo *bo) return ret; } - bo->bo_reuse = FALSE; + bo->bo_reuse = NO_CACHE; return prime_fd; } diff --git a/freedreno/freedreno_device.c b/freedreno/freedreno_device.c index 0b42561a..001b05ad 100644 --- a/freedreno/freedreno_device.c +++ b/freedreno/freedreno_device.c @@ -82,6 +82,7 @@ out: dev->handle_table = drmHashCreate(); dev->name_table = drmHashCreate(); fd_bo_cache_init(&dev->bo_cache, FALSE); + fd_bo_cache_init(&dev->ring_cache, TRUE); return dev; } diff --git a/freedreno/freedreno_priv.h b/freedreno/freedreno_priv.h index 9d51c368..84dbc5c6 100644 --- a/freedreno/freedreno_priv.h +++ b/freedreno/freedreno_priv.h @@ -98,6 +98,7 @@ struct fd_device { const struct fd_device_funcs *funcs; struct fd_bo_cache bo_cache; + struct fd_bo_cache ring_cache; int closefd; /* call close(fd) upon destruction */ @@ -172,11 +173,19 @@ struct fd_bo { atomic_t refcnt; const struct fd_bo_funcs *funcs; - int bo_reuse; + enum { + NO_CACHE = 0, + BO_CACHE = 1, + RING_CACHE = 2, + } bo_reuse; + struct list_head list; /* bucket-list entry */ time_t free_time; /* time when added to bucket-list */ }; +drm_private struct fd_bo *fd_bo_new_ring(struct fd_device *dev, + uint32_t size, uint32_t flags); + #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) #define enable_debug 0 /* TODO make dynamic */ diff --git a/freedreno/msm/msm_device.c b/freedreno/msm/msm_device.c index 7bb57677..58b0746d 100644 --- a/freedreno/msm/msm_device.c +++ b/freedreno/msm/msm_device.c @@ -35,7 +35,6 @@ static void msm_device_destroy(struct fd_device *dev) { struct msm_device *msm_dev = to_msm_device(dev); - fd_bo_cache_cleanup(&msm_dev->ring_cache, 0); free(msm_dev); } @@ -58,8 +57,6 @@ drm_private struct fd_device * msm_device_new(int fd) dev = &msm_dev->base; dev->funcs = &funcs; - fd_bo_cache_init(&msm_dev->ring_cache, TRUE); - dev->bo_size = sizeof(struct msm_bo); return dev; diff --git a/freedreno/msm/msm_ringbuffer.c b/freedreno/msm/msm_ringbuffer.c index 35a7a7d4..ac6221c2 100644 --- a/freedreno/msm/msm_ringbuffer.c +++ b/freedreno/msm/msm_ringbuffer.c @@ -103,46 +103,11 @@ static void msm_ringbuffer_ref(struct fd_ringbuffer *ring); #define INIT_SIZE 0x1000 static pthread_mutex_t idx_lock = PTHREAD_MUTEX_INITIALIZER; -drm_private extern pthread_mutex_t table_lock; - -static void ring_bo_del(struct fd_device *dev, struct fd_bo *bo) -{ - int ret; - - assert(atomic_read(&bo->refcnt) == 1); - - pthread_mutex_lock(&table_lock); - ret = fd_bo_cache_free(&to_msm_device(dev)->ring_cache, bo); - pthread_mutex_unlock(&table_lock); - - if (ret == 0) - return; - - fd_bo_del(bo); -} - -static struct fd_bo * ring_bo_new(struct fd_device *dev, uint32_t size) -{ - struct fd_bo *bo; - - bo = fd_bo_cache_alloc(&to_msm_device(dev)->ring_cache, &size, 0); - if (bo) - return bo; - - bo = fd_bo_new(dev, size, 0); - if (!bo) - return NULL; - - /* keep ringbuffer bo's out of the normal bo cache: */ - bo->bo_reuse = FALSE; - - return bo; -} static void ring_cmd_del(struct msm_cmd *cmd) { if (cmd->ring_bo) - ring_bo_del(cmd->ring->pipe->dev, cmd->ring_bo); + fd_bo_del(cmd->ring_bo); list_del(&cmd->list); to_msm_ringbuffer(cmd->ring)->cmd_count--; free(cmd->relocs); @@ -158,7 +123,7 @@ static struct msm_cmd * ring_cmd_new(struct fd_ringbuffer *ring, uint32_t size) return NULL; cmd->ring = ring; - cmd->ring_bo = ring_bo_new(ring->pipe->dev, size); + cmd->ring_bo = fd_bo_new_ring(ring->pipe->dev, size, 0); if (!cmd->ring_bo) goto fail; -- 2.11.0