]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/commitdiff
drm_mm: add support for range-restricted fair-lru scans
authorDaniel Vetter <daniel.vetter@ffwll.ch>
Thu, 16 Sep 2010 13:13:11 +0000 (15:13 +0200)
committerChris Wilson <chris@chris-wilson.co.uk>
Wed, 27 Oct 2010 22:31:04 +0000 (23:31 +0100)
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
drivers/gpu/drm/drm_mm.c
include/drm/drm_mm.h

index a6bfc302ed909ecf136888953b329d5acbdf65a3..c59515ba7e69c1b3abad019a6f0cb281deeab6a6 100644 (file)
@@ -392,9 +392,35 @@ void drm_mm_init_scan(struct drm_mm *mm, unsigned long size,
        mm->scanned_blocks = 0;
        mm->scan_hit_start = 0;
        mm->scan_hit_size = 0;
+       mm->scan_check_range = 0;
 }
 EXPORT_SYMBOL(drm_mm_init_scan);
 
+/**
+ * Initializa lru scanning.
+ *
+ * This simply sets up the scanning routines with the parameters for the desired
+ * hole. This version is for range-restricted scans.
+ *
+ * Warning: As long as the scan list is non-empty, no other operations than
+ * adding/removing nodes to/from the scan list are allowed.
+ */
+void drm_mm_init_scan_with_range(struct drm_mm *mm, unsigned long size,
+                                unsigned alignment,
+                                unsigned long start,
+                                unsigned long end)
+{
+       mm->scan_alignment = alignment;
+       mm->scan_size = size;
+       mm->scanned_blocks = 0;
+       mm->scan_hit_start = 0;
+       mm->scan_hit_size = 0;
+       mm->scan_start = start;
+       mm->scan_end = end;
+       mm->scan_check_range = 1;
+}
+EXPORT_SYMBOL(drm_mm_init_scan_with_range);
+
 /**
  * Add a node to the scan list that might be freed to make space for the desired
  * hole.
@@ -406,6 +432,8 @@ int drm_mm_scan_add_block(struct drm_mm_node *node)
        struct drm_mm *mm = node->mm;
        struct list_head *prev_free, *next_free;
        struct drm_mm_node *prev_node, *next_node;
+       unsigned long adj_start;
+       unsigned long adj_end;
 
        mm->scanned_blocks++;
 
@@ -452,7 +480,17 @@ int drm_mm_scan_add_block(struct drm_mm_node *node)
        node->free_stack.prev = prev_free;
        node->free_stack.next = next_free;
 
-       if (check_free_hole(node->start, node->start + node->size,
+       if (mm->scan_check_range) {
+               adj_start = node->start < mm->scan_start ?
+                       mm->scan_start : node->start;
+               adj_end = node->start + node->size > mm->scan_end ?
+                       mm->scan_end : node->start + node->size;
+       } else {
+               adj_start = node->start;
+               adj_end = node->start + node->size;
+       }
+
+       if (check_free_hole(adj_start , adj_end,
                            mm->scan_size, mm->scan_alignment)) {
                mm->scan_hit_start = node->start;
                mm->scan_hit_size = node->size;
index bf01531193d530640bbdedb69c86d49d14c81ea0..e39177778601a983e6adff40775ae2cf77d3b2d4 100644 (file)
@@ -62,11 +62,14 @@ struct drm_mm {
        struct list_head unused_nodes;
        int num_unused;
        spinlock_t unused_lock;
+       unsigned int scan_check_range : 1;
        unsigned scan_alignment;
        unsigned long scan_size;
        unsigned long scan_hit_start;
        unsigned scan_hit_size;
        unsigned scanned_blocks;
+       unsigned long scan_start;
+       unsigned long scan_end;
 };
 
 /*
@@ -145,6 +148,10 @@ static inline struct drm_mm *drm_get_mm(struct drm_mm_node *block)
 
 void drm_mm_init_scan(struct drm_mm *mm, unsigned long size,
                      unsigned alignment);
+void drm_mm_init_scan_with_range(struct drm_mm *mm, unsigned long size,
+                                unsigned alignment,
+                                unsigned long start,
+                                unsigned long end);
 int drm_mm_scan_add_block(struct drm_mm_node *node);
 int drm_mm_scan_remove_block(struct drm_mm_node *node);