summaryrefslogtreecommitdiffstats
path: root/src/gallium/winsys/radeon
diff options
context:
space:
mode:
authorMichel Dänzer <[email protected]>2012-04-26 15:26:01 +0200
committerMichel Dänzer <[email protected]>2012-08-16 09:39:36 +0200
commit206d07625c9fd69c7d00a8722bd7390c5215bfe2 (patch)
treebe9c3172a2c4b1467e2d21e41646f318dbee808e /src/gallium/winsys/radeon
parentc25968f3e2a1b5144a2e88d15b95e5b477a55f5d (diff)
gallium/radeon: Merge holes when freeing virtual address space.
Otherwise we'll likely end up with an ever increasing amount of ever smaller holes. Requires keeping the list ordered wrt offsets. Signed-off-by: Michel Dänzer <[email protected]> Reviewed-by: Alex Deucher <[email protected]>
Diffstat (limited to 'src/gallium/winsys/radeon')
-rw-r--r--src/gallium/winsys/radeon/drm/radeon_drm_bo.c45
1 files changed, 38 insertions, 7 deletions
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c
index 4c899010226..f09e7e819cb 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c
@@ -226,7 +226,7 @@ static uint64_t radeon_bomgr_find_va(struct radeon_bomgr *mgr, uint64_t size, ui
n = CALLOC_STRUCT(radeon_bo_va_hole);
n->size = waste;
n->offset = hole->offset;
- list_add(&n->list, &mgr->va_holes);
+ list_add(&n->list, &hole->list);
}
hole->size -= (size + waste);
hole->offset += size + waste;
@@ -286,18 +286,49 @@ static void radeon_bomgr_free_va(struct radeon_bomgr *mgr, uint64_t va, uint64_t
if ((va + size) == mgr->va_offset) {
mgr->va_offset = va;
} else {
- struct radeon_bo_va_hole *hole;
+ struct radeon_bo_va_hole *hole, *next;
+
+ hole = container_of(&mgr->va_holes, hole, list);
+ LIST_FOR_EACH_ENTRY(next, &mgr->va_holes, list) {
+ if (next->offset < va)
+ break;
+ hole = next;
+ }
+
+ if (&hole->list != &mgr->va_holes) {
+ /* Grow upper hole if it's adjacent */
+ if (hole->offset == (va + size)) {
+ hole->offset = va;
+ hole->size += size;
+ /* Merge lower hole if it's adjacent */
+ if (next != hole && &next->list != &mgr->va_holes &&
+ (next->offset + next->size) == va) {
+ next->size += hole->size;
+ list_del(&hole->list);
+ FREE(hole);
+ }
+ goto out;
+ }
+ }
+
+ /* Grow lower hole if it's adjacent */
+ if (next != hole && &next->list != &mgr->va_holes &&
+ (next->offset + next->size) == va) {
+ next->size += size;
+ goto out;
+ }
/* FIXME on allocation failure we just lose virtual address space
* maybe print a warning
*/
- hole = CALLOC_STRUCT(radeon_bo_va_hole);
- if (hole) {
- hole->size = size;
- hole->offset = va;
- list_add(&hole->list, &mgr->va_holes);
+ next = CALLOC_STRUCT(radeon_bo_va_hole);
+ if (next) {
+ next->size = size;
+ next->offset = va;
+ list_add(&next->list, &hole->list);
}
}
+out:
pipe_mutex_unlock(mgr->bo_va_mutex);
}