diff options
Diffstat (limited to 'freedreno')
-rw-r--r-- | freedreno/freedreno_bo.c | 81 | ||||
-rw-r--r-- | freedreno/freedreno_device.c | 4 | ||||
-rw-r--r-- | freedreno/freedreno_priv.h | 6 |
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 */ |
87 | drm_private void fd_cleanup_bo_cache(struct fd_bo_cache *cache, time_t time) | 87 | drm_private void |
88 | fd_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: */ | |
172 | struct fd_bo * | 173 | drm_private struct fd_bo * |
173 | fd_bo_new(struct fd_device *dev, uint32_t size, uint32_t flags) | 174 | fd_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 | |||
196 | struct fd_bo * | ||
197 | fd_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 | ||
293 | void fd_bo_del(struct fd_bo *bo) | 306 | drm_private int |
307 | fd_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 | 332 | void 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); |
324 | out: | ||
325 | fd_device_del_locked(dev); | 345 | fd_device_del_locked(dev); |
346 | out: | ||
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 | ||
57 | static void | 57 | drm_private void |
58 | fd_bo_cache_init(struct fd_bo_cache *cache) | 58 | fd_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 | ||
138 | static void fd_device_del_impl(struct fd_device *dev) | 138 | static 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 | ||
99 | drm_private void fd_cleanup_bo_cache(struct fd_bo_cache *cache, time_t time); | 99 | drm_private void fd_bo_cache_init(struct fd_bo_cache *cache); |
100 | drm_private void fd_bo_cache_cleanup(struct fd_bo_cache *cache, time_t time); | ||
101 | drm_private struct fd_bo * fd_bo_cache_alloc(struct fd_bo_cache *cache, | ||
102 | uint32_t *size, uint32_t flags); | ||
103 | drm_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: */ |
102 | drm_private void fd_device_del_locked(struct fd_device *dev); | 106 | drm_private void fd_device_del_locked(struct fd_device *dev); |