drm/mm: Fix search for smallest hole satisfying constraints
authorMichel Dänzer <michel.daenzer@amd.com>
Wed, 19 Mar 2014 08:37:14 +0000 (17:37 +0900)
committerDave Airlie <airlied@redhat.com>
Fri, 4 Apr 2014 00:12:21 +0000 (10:12 +1000)
entry->size is the size of the node, not the size of the hole after it.
So the code would actually find the hole which can satisfy the
constraints and which is preceded by the smallest node, not the smallest
hole satisfying the constraints.

Reported-by: "Huang, FrankR" <FrankR.Huang@amd.com>
Signed-off-by: Michel Dänzer <michel.daenzer@amd.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
drivers/gpu/drm/drm_mm.c

index 8f64be44bfe784f832c47066722acebaec554cef..71e2d3fcd6ee3c17b589cdfb7cc8baf142605bfd 100644 (file)
@@ -423,6 +423,8 @@ static struct drm_mm_node *drm_mm_search_free_generic(const struct drm_mm *mm,
 
        __drm_mm_for_each_hole(entry, mm, adj_start, adj_end,
                               flags & DRM_MM_SEARCH_BELOW) {
+               unsigned long hole_size = adj_end - adj_start;
+
                if (mm->color_adjust) {
                        mm->color_adjust(entry, color, &adj_start, &adj_end);
                        if (adj_end <= adj_start)
@@ -435,9 +437,9 @@ static struct drm_mm_node *drm_mm_search_free_generic(const struct drm_mm *mm,
                if (!(flags & DRM_MM_SEARCH_BEST))
                        return entry;
 
-               if (entry->size < best_size) {
+               if (hole_size < best_size) {
                        best = entry;
-                       best_size = entry->size;
+                       best_size = hole_size;
                }
        }
 
@@ -465,6 +467,8 @@ static struct drm_mm_node *drm_mm_search_free_in_range_generic(const struct drm_
 
        __drm_mm_for_each_hole(entry, mm, adj_start, adj_end,
                               flags & DRM_MM_SEARCH_BELOW) {
+               unsigned long hole_size = adj_end - adj_start;
+
                if (adj_start < start)
                        adj_start = start;
                if (adj_end > end)
@@ -482,9 +486,9 @@ static struct drm_mm_node *drm_mm_search_free_in_range_generic(const struct drm_
                if (!(flags & DRM_MM_SEARCH_BEST))
                        return entry;
 
-               if (entry->size < best_size) {
+               if (hole_size < best_size) {
                        best = entry;
-                       best_size = entry->size;
+                       best_size = hole_size;
                }
        }