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
parent
3b64b54e32
commit
28328298ca
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue