summaryrefslogtreecommitdiff
path: root/freedreno
diff options
context:
space:
mode:
authorRob Clark <robclark@freedesktop.org>2018-08-17 15:58:17 -0400
committerRob Clark <robclark@freedesktop.org>2018-09-14 13:41:44 -0400
commit28328298ca94344538a0d7f41350810f086900ee (patch)
treee44742efeae7be4bfe48c46eed94d79e399ec0f1 /freedreno
parent3b64b54e32caa3b10358ac41c59d1e48a9e5b2c8 (diff)
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>
Diffstat (limited to 'freedreno')
-rw-r--r--freedreno/freedreno_bo.c39
-rw-r--r--freedreno/freedreno_device.c1
-rw-r--r--freedreno/freedreno_priv.h11
-rw-r--r--freedreno/msm/msm_device.c3
-rw-r--r--freedreno/msm/msm_ringbuffer.c39
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;