drm: Optimise power-of-two alignments in drm_mm_scan_add_block()
authorChris Wilson <chris@chris-wilson.co.uk>
Thu, 22 Dec 2016 08:36:34 +0000 (08:36 +0000)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Wed, 28 Dec 2016 10:51:52 +0000 (11:51 +0100)
For power-of-two alignments, we can avoid the 64bit divide and do a
simple bitwise add instead.

v2: s/alignment_mask/remainder_mask/

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: http://patchwork.freedesktop.org/patch/msgid/20161222083641.2691-32-chris@chris-wilson.co.uk
drivers/gpu/drm/drm_mm.c
include/drm/drm_mm.h

index 189ab84c5a592c29a131f8e0612c99fa8c08ecf6..0441d84fba74ac8b04f7e377a129a78d9eb89d9c 100644 (file)
@@ -742,8 +742,12 @@ void drm_mm_scan_init_with_range(struct drm_mm_scan *scan,
 
        scan->mm = mm;
 
+       if (alignment <= 1)
+               alignment = 0;
+
        scan->color = color;
        scan->alignment = alignment;
+       scan->remainder_mask = is_power_of_2(alignment) ? alignment - 1 : 0;
        scan->size = size;
        scan->flags = flags;
 
@@ -811,7 +815,10 @@ bool drm_mm_scan_add_block(struct drm_mm_scan *scan,
        if (scan->alignment) {
                u64 rem;
 
-               div64_u64_rem(adj_start, scan->alignment, &rem);
+               if (likely(scan->remainder_mask))
+                       rem = adj_start & scan->remainder_mask;
+               else
+                       div64_u64_rem(adj_start, scan->alignment, &rem);
                if (rem) {
                        adj_start -= rem;
                        if (scan->flags != DRM_MM_CREATE_TOP)
index 606336fc229a8a6ebbefd3bdba49c73b67824e1b..d6701d56ea74246b1da183a3969087128c82c4c8 100644 (file)
@@ -110,6 +110,7 @@ struct drm_mm_scan {
 
        u64 size;
        u64 alignment;
+       u64 remainder_mask;
 
        u64 range_start;
        u64 range_end;