aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'freedreno')
-rw-r--r--freedreno/freedreno_bo.c81
-rw-r--r--freedreno/freedreno_device.c4
-rw-r--r--freedreno/freedreno_priv.h6
3 files changed, 58 insertions, 33 deletions
diff --git a/freedreno/freedreno_bo.c b/freedreno/freedreno_bo.c
index 7b3e51f1..da563983 100644
--- a/freedreno/freedreno_bo.c
+++ b/freedreno/freedreno_bo.c
@@ -84,7 +84,8 @@ static struct fd_bo * bo_from_handle(struct fd_device *dev,
84} 84}
85 85
86/* Frees older cached buffers. Called under table_lock */ 86/* Frees older cached buffers. Called under table_lock */
87drm_private void fd_cleanup_bo_cache(struct fd_bo_cache *cache, time_t time) 87drm_private void
88fd_bo_cache_cleanup(struct fd_bo_cache *cache, time_t time)
88{ 89{
89 int i; 90 int i;
90 91
@@ -168,21 +169,19 @@ static struct fd_bo *find_in_bucket(struct fd_bo_bucket *bucket, uint32_t flags)
168 return bo; 169 return bo;
169} 170}
170 171
171 172/* NOTE: size is potentially rounded up to bucket size: */
172struct fd_bo * 173drm_private struct fd_bo *
173fd_bo_new(struct fd_device *dev, uint32_t size, uint32_t flags) 174fd_bo_cache_alloc(struct fd_bo_cache *cache, uint32_t *size, uint32_t flags)
174{ 175{
175 struct fd_bo *bo = NULL; 176 struct fd_bo *bo = NULL;
176 struct fd_bo_bucket *bucket; 177 struct fd_bo_bucket *bucket;
177 uint32_t handle;
178 int ret;
179 178
180 size = ALIGN(size, 4096); 179 *size = ALIGN(*size, 4096);
181 bucket = get_bucket(&dev->bo_cache, size); 180 bucket = get_bucket(cache, *size);
182 181
183 /* see if we can be green and recycle: */ 182 /* see if we can be green and recycle: */
184 if (bucket) { 183 if (bucket) {
185 size = bucket->size; 184 *size = bucket->size;
186 bo = find_in_bucket(bucket, flags); 185 bo = find_in_bucket(bucket, flags);
187 if (bo) { 186 if (bo) {
188 atomic_set(&bo->refcnt, 1); 187 atomic_set(&bo->refcnt, 1);
@@ -191,6 +190,20 @@ fd_bo_new(struct fd_device *dev, uint32_t size, uint32_t flags)
191 } 190 }
192 } 191 }
193 192
193 return NULL;
194}
195
196struct fd_bo *
197fd_bo_new(struct fd_device *dev, uint32_t size, uint32_t flags)
198{
199 struct fd_bo *bo = NULL;
200 uint32_t handle;
201 int ret;
202
203 bo = fd_bo_cache_alloc(&dev->bo_cache, &size, flags);
204 if (bo)
205 return bo;
206
194 ret = dev->funcs->bo_new_handle(dev, size, flags, &handle); 207 ret = dev->funcs->bo_new_handle(dev, size, flags, &handle);
195 if (ret) 208 if (ret)
196 return NULL; 209 return NULL;
@@ -290,39 +303,47 @@ struct fd_bo * fd_bo_ref(struct fd_bo *bo)
290 return bo; 303 return bo;
291} 304}
292 305
293void fd_bo_del(struct fd_bo *bo) 306drm_private int
307fd_bo_cache_free(struct fd_bo_cache *cache, struct fd_bo *bo)
294{ 308{
295 struct fd_device *dev = bo->dev; 309 struct fd_bo_bucket *bucket = get_bucket(cache, bo->size);
296 310
297 if (!atomic_dec_and_test(&bo->refcnt)) 311 /* see if we can be green and recycle: */
298 return; 312 if (bucket) {
313 struct timespec time;
299 314
300 pthread_mutex_lock(&table_lock); 315 clock_gettime(CLOCK_MONOTONIC, &time);
301 316
302 if (bo->bo_reuse) { 317 bo->free_time = time.tv_sec;
303 struct fd_bo_bucket *bucket = get_bucket(&dev->bo_cache, bo->size); 318 list_addtail(&bo->list, &bucket->list);
319 fd_bo_cache_cleanup(cache, time.tv_sec);
304 320
305 /* see if we can be green and recycle: */ 321 /* bo's in the bucket cache don't have a ref and
306 if (bucket) { 322 * don't hold a ref to the dev:
307 struct timespec time; 323 */
324 fd_device_del_locked(bo->dev);
308 325
309 clock_gettime(CLOCK_MONOTONIC, &time); 326 return 0;
327 }
310 328
311 bo->free_time = time.tv_sec; 329 return -1;
312 list_addtail(&bo->list, &bucket->list); 330}
313 fd_cleanup_bo_cache(&dev->bo_cache, time.tv_sec);
314 331
315 /* bo's in the bucket cache don't have a ref and 332void fd_bo_del(struct fd_bo *bo)
316 * don't hold a ref to the dev: 333{
317 */ 334 struct fd_device *dev = bo->dev;
318 335
319 goto out; 336 if (!atomic_dec_and_test(&bo->refcnt))
320 } 337 return;
321 } 338
339 pthread_mutex_lock(&table_lock);
340
341 if (bo->bo_reuse && (fd_bo_cache_free(&dev->bo_cache, bo) == 0))
342 goto out;
322 343
323 bo_del(bo); 344 bo_del(bo);
324out:
325 fd_device_del_locked(dev); 345 fd_device_del_locked(dev);
346out:
326 pthread_mutex_unlock(&table_lock); 347 pthread_mutex_unlock(&table_lock);
327} 348}
328 349
diff --git a/freedreno/freedreno_device.c b/freedreno/freedreno_device.c
index 0e20332e..bd57c249 100644
--- a/freedreno/freedreno_device.c
+++ b/freedreno/freedreno_device.c
@@ -54,7 +54,7 @@ add_bucket(struct fd_bo_cache *cache, int size)
54 cache->num_buckets++; 54 cache->num_buckets++;
55} 55}
56 56
57static void 57drm_private void
58fd_bo_cache_init(struct fd_bo_cache *cache) 58fd_bo_cache_init(struct fd_bo_cache *cache)
59{ 59{
60 unsigned long size, cache_max_size = 64 * 1024 * 1024; 60 unsigned long size, cache_max_size = 64 * 1024 * 1024;
@@ -137,7 +137,7 @@ struct fd_device * fd_device_ref(struct fd_device *dev)
137 137
138static void fd_device_del_impl(struct fd_device *dev) 138static void fd_device_del_impl(struct fd_device *dev)
139{ 139{
140 fd_cleanup_bo_cache(&dev->bo_cache, 0); 140 fd_bo_cache_cleanup(&dev->bo_cache, 0);
141 drmHashDestroy(dev->handle_table); 141 drmHashDestroy(dev->handle_table);
142 drmHashDestroy(dev->name_table); 142 drmHashDestroy(dev->name_table);
143 if (dev->closefd) 143 if (dev->closefd)
diff --git a/freedreno/freedreno_priv.h b/freedreno/freedreno_priv.h
index 5880dc25..4159e526 100644
--- a/freedreno/freedreno_priv.h
+++ b/freedreno/freedreno_priv.h
@@ -96,7 +96,11 @@ struct fd_device {
96 int closefd; /* call close(fd) upon destruction */ 96 int closefd; /* call close(fd) upon destruction */
97}; 97};
98 98
99drm_private void fd_cleanup_bo_cache(struct fd_bo_cache *cache, time_t time); 99drm_private void fd_bo_cache_init(struct fd_bo_cache *cache);
100drm_private void fd_bo_cache_cleanup(struct fd_bo_cache *cache, time_t time);
101drm_private struct fd_bo * fd_bo_cache_alloc(struct fd_bo_cache *cache,
102 uint32_t *size, uint32_t flags);
103drm_private int fd_bo_cache_free(struct fd_bo_cache *cache, struct fd_bo *bo);
100 104
101/* for where @table_lock is already held: */ 105/* for where @table_lock is already held: */
102drm_private void fd_device_del_locked(struct fd_device *dev); 106drm_private void fd_device_del_locked(struct fd_device *dev);