drm: Convert drm_vma_manager to embedded interval-tree in drm_mm

Having added an interval-tree to struct drm_mm, we can replace the
auxiliary rb-tree inside the drm_vma_manager with it.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: David Herrmann <dh.herrmann@gmail.com>
Cc: dri-devel@lists.freedesktop.org
Reviewed-by: David Herrmann <dh.herrmann@gmail.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: http://patchwork.freedesktop.org/patch/msgid/1470236651-678-2-git-send-email-chris@chris-wilson.co.uk
This commit is contained in:
Chris Wilson 2016-08-03 16:04:10 +01:00 committed by Daniel Vetter
parent 202b52b7fb
commit db2395eccf
2 changed files with 9 additions and 36 deletions

View File

@ -86,7 +86,6 @@ void drm_vma_offset_manager_init(struct drm_vma_offset_manager *mgr,
unsigned long page_offset, unsigned long size) unsigned long page_offset, unsigned long size)
{ {
rwlock_init(&mgr->vm_lock); rwlock_init(&mgr->vm_lock);
mgr->vm_addr_space_rb = RB_ROOT;
drm_mm_init(&mgr->vm_addr_space_mm, page_offset, size); drm_mm_init(&mgr->vm_addr_space_mm, page_offset, size);
} }
EXPORT_SYMBOL(drm_vma_offset_manager_init); EXPORT_SYMBOL(drm_vma_offset_manager_init);
@ -145,16 +144,16 @@ struct drm_vma_offset_node *drm_vma_offset_lookup_locked(struct drm_vma_offset_m
unsigned long start, unsigned long start,
unsigned long pages) unsigned long pages)
{ {
struct drm_vma_offset_node *node, *best; struct drm_mm_node *node, *best;
struct rb_node *iter; struct rb_node *iter;
unsigned long offset; unsigned long offset;
iter = mgr->vm_addr_space_rb.rb_node; iter = mgr->vm_addr_space_mm.interval_tree.rb_node;
best = NULL; best = NULL;
while (likely(iter)) { while (likely(iter)) {
node = rb_entry(iter, struct drm_vma_offset_node, vm_rb); node = rb_entry(iter, struct drm_mm_node, rb);
offset = node->vm_node.start; offset = node->start;
if (start >= offset) { if (start >= offset) {
iter = iter->rb_right; iter = iter->rb_right;
best = node; best = node;
@ -167,39 +166,18 @@ struct drm_vma_offset_node *drm_vma_offset_lookup_locked(struct drm_vma_offset_m
/* verify that the node spans the requested area */ /* verify that the node spans the requested area */
if (best) { if (best) {
offset = best->vm_node.start + best->vm_node.size; offset = best->start + best->size;
if (offset < start + pages) if (offset < start + pages)
best = NULL; best = NULL;
} }
return best; if (!best)
return NULL;
return container_of(best, struct drm_vma_offset_node, vm_node);
} }
EXPORT_SYMBOL(drm_vma_offset_lookup_locked); EXPORT_SYMBOL(drm_vma_offset_lookup_locked);
/* internal helper to link @node into the rb-tree */
static void _drm_vma_offset_add_rb(struct drm_vma_offset_manager *mgr,
struct drm_vma_offset_node *node)
{
struct rb_node **iter = &mgr->vm_addr_space_rb.rb_node;
struct rb_node *parent = NULL;
struct drm_vma_offset_node *iter_node;
while (likely(*iter)) {
parent = *iter;
iter_node = rb_entry(*iter, struct drm_vma_offset_node, vm_rb);
if (node->vm_node.start < iter_node->vm_node.start)
iter = &(*iter)->rb_left;
else if (node->vm_node.start > iter_node->vm_node.start)
iter = &(*iter)->rb_right;
else
BUG();
}
rb_link_node(&node->vm_rb, parent, iter);
rb_insert_color(&node->vm_rb, &mgr->vm_addr_space_rb);
}
/** /**
* drm_vma_offset_add() - Add offset node to manager * drm_vma_offset_add() - Add offset node to manager
* @mgr: Manager object * @mgr: Manager object
@ -240,8 +218,6 @@ int drm_vma_offset_add(struct drm_vma_offset_manager *mgr,
if (ret) if (ret)
goto out_unlock; goto out_unlock;
_drm_vma_offset_add_rb(mgr, node);
out_unlock: out_unlock:
write_unlock(&mgr->vm_lock); write_unlock(&mgr->vm_lock);
return ret; return ret;
@ -265,7 +241,6 @@ void drm_vma_offset_remove(struct drm_vma_offset_manager *mgr,
write_lock(&mgr->vm_lock); write_lock(&mgr->vm_lock);
if (drm_mm_node_allocated(&node->vm_node)) { if (drm_mm_node_allocated(&node->vm_node)) {
rb_erase(&node->vm_rb, &mgr->vm_addr_space_rb);
drm_mm_remove_node(&node->vm_node); drm_mm_remove_node(&node->vm_node);
memset(&node->vm_node, 0, sizeof(node->vm_node)); memset(&node->vm_node, 0, sizeof(node->vm_node));
} }

View File

@ -40,13 +40,11 @@ struct drm_vma_offset_file {
struct drm_vma_offset_node { struct drm_vma_offset_node {
rwlock_t vm_lock; rwlock_t vm_lock;
struct drm_mm_node vm_node; struct drm_mm_node vm_node;
struct rb_node vm_rb;
struct rb_root vm_files; struct rb_root vm_files;
}; };
struct drm_vma_offset_manager { struct drm_vma_offset_manager {
rwlock_t vm_lock; rwlock_t vm_lock;
struct rb_root vm_addr_space_rb;
struct drm_mm vm_addr_space_mm; struct drm_mm vm_addr_space_mm;
}; };