freedreno: move ring_cache behind fd_bo_del()

So that it isn't bypassing normal refcnt'ing.

Signed-off-by: Rob Clark <robclark@freedesktop.org>
main
Rob Clark 2018-08-17 15:58:17 -04:00
parent 3b64b54e32
commit 28328298ca
5 changed files with 45 additions and 48 deletions

View File

@ -78,14 +78,15 @@ static struct fd_bo * bo_from_handle(struct fd_device *dev,
return bo; return bo;
} }
struct fd_bo * static struct fd_bo *
fd_bo_new(struct fd_device *dev, uint32_t size, uint32_t flags) bo_new(struct fd_device *dev, uint32_t size, uint32_t flags,
struct fd_bo_cache *cache)
{ {
struct fd_bo *bo = NULL; struct fd_bo *bo = NULL;
uint32_t handle; uint32_t handle;
int ret; int ret;
bo = fd_bo_cache_alloc(&dev->bo_cache, &size, flags); bo = fd_bo_cache_alloc(cache, &size, flags);
if (bo) if (bo)
return 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); pthread_mutex_lock(&table_lock);
bo = bo_from_handle(dev, size, handle); bo = bo_from_handle(dev, size, handle);
bo->bo_reuse = TRUE;
pthread_mutex_unlock(&table_lock); pthread_mutex_unlock(&table_lock);
VG_BO_ALLOC(bo); VG_BO_ALLOC(bo);
@ -103,6 +103,29 @@ fd_bo_new(struct fd_device *dev, uint32_t size, uint32_t flags)
return bo; return bo;
} }
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 * struct fd_bo *
fd_bo_from_handle(struct fd_device *dev, uint32_t handle, uint32_t size) fd_bo_from_handle(struct fd_device *dev, uint32_t handle, uint32_t size)
{ {
@ -216,7 +239,9 @@ void fd_bo_del(struct fd_bo *bo)
pthread_mutex_lock(&table_lock); 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; goto out;
bo_del(bo); bo_del(bo);
@ -266,7 +291,7 @@ int fd_bo_get_name(struct fd_bo *bo, uint32_t *name)
pthread_mutex_lock(&table_lock); pthread_mutex_lock(&table_lock);
set_name(bo, req.name); set_name(bo, req.name);
pthread_mutex_unlock(&table_lock); pthread_mutex_unlock(&table_lock);
bo->bo_reuse = FALSE; bo->bo_reuse = NO_CACHE;
} }
*name = bo->name; *name = bo->name;
@ -290,7 +315,7 @@ int fd_bo_dmabuf(struct fd_bo *bo)
return ret; return ret;
} }
bo->bo_reuse = FALSE; bo->bo_reuse = NO_CACHE;
return prime_fd; return prime_fd;
} }

View File

@ -82,6 +82,7 @@ out:
dev->handle_table = drmHashCreate(); dev->handle_table = drmHashCreate();
dev->name_table = drmHashCreate(); dev->name_table = drmHashCreate();
fd_bo_cache_init(&dev->bo_cache, FALSE); fd_bo_cache_init(&dev->bo_cache, FALSE);
fd_bo_cache_init(&dev->ring_cache, TRUE);
return dev; return dev;
} }

View File

@ -98,6 +98,7 @@ struct fd_device {
const struct fd_device_funcs *funcs; const struct fd_device_funcs *funcs;
struct fd_bo_cache bo_cache; struct fd_bo_cache bo_cache;
struct fd_bo_cache ring_cache;
int closefd; /* call close(fd) upon destruction */ int closefd; /* call close(fd) upon destruction */
@ -172,11 +173,19 @@ struct fd_bo {
atomic_t refcnt; atomic_t refcnt;
const struct fd_bo_funcs *funcs; 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 */ struct list_head list; /* bucket-list entry */
time_t free_time; /* time when added to bucket-list */ 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 ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
#define enable_debug 0 /* TODO make dynamic */ #define enable_debug 0 /* TODO make dynamic */

View File

@ -35,7 +35,6 @@
static void msm_device_destroy(struct fd_device *dev) static void msm_device_destroy(struct fd_device *dev)
{ {
struct msm_device *msm_dev = to_msm_device(dev); struct msm_device *msm_dev = to_msm_device(dev);
fd_bo_cache_cleanup(&msm_dev->ring_cache, 0);
free(msm_dev); free(msm_dev);
} }
@ -58,8 +57,6 @@ drm_private struct fd_device * msm_device_new(int fd)
dev = &msm_dev->base; dev = &msm_dev->base;
dev->funcs = &funcs; dev->funcs = &funcs;
fd_bo_cache_init(&msm_dev->ring_cache, TRUE);
dev->bo_size = sizeof(struct msm_bo); dev->bo_size = sizeof(struct msm_bo);
return dev; return dev;

View File

@ -103,46 +103,11 @@ static void msm_ringbuffer_ref(struct fd_ringbuffer *ring);
#define INIT_SIZE 0x1000 #define INIT_SIZE 0x1000
static pthread_mutex_t idx_lock = PTHREAD_MUTEX_INITIALIZER; 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) static void ring_cmd_del(struct msm_cmd *cmd)
{ {
if (cmd->ring_bo) if (cmd->ring_bo)
ring_bo_del(cmd->ring->pipe->dev, cmd->ring_bo); fd_bo_del(cmd->ring_bo);
list_del(&cmd->list); list_del(&cmd->list);
to_msm_ringbuffer(cmd->ring)->cmd_count--; to_msm_ringbuffer(cmd->ring)->cmd_count--;
free(cmd->relocs); free(cmd->relocs);
@ -158,7 +123,7 @@ static struct msm_cmd * ring_cmd_new(struct fd_ringbuffer *ring, uint32_t size)
return NULL; return NULL;
cmd->ring = ring; 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) if (!cmd->ring_bo)
goto fail; goto fail;