Am 27.11.2016 um 20:05 schrieb Chris Wilson: > In places (e.g. i915.ko), the alignment is exported to userspace as u64 > and there now exists hardware for which we can indeed utilize a u64 > alignment. As such, we need to keep 64bit integers throughout when > handling alignment. > > Testcase: igt/drm_mm/align64 > Testcase: igt/gem_exec_alignment > Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk> > Cc: Joonas Lahtinen <joonas.lahtinen at linux.intel.com>
Reviewed-by: Christian König <christian.koenig at amd.com>. And yeah, we have a couple of use cases aligning something to a 4GB boundary in a large address space as well. Regards, Christian. > --- > drivers/gpu/drm/drm_mm.c | 37 +++++++++++++++++-------------------- > include/drm/drm_mm.h | 16 ++++++++-------- > 2 files changed, 25 insertions(+), 28 deletions(-) > > diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c > index 025dcd8cadcb..b5b0b667677d 100644 > --- a/drivers/gpu/drm/drm_mm.c > +++ b/drivers/gpu/drm/drm_mm.c > @@ -93,12 +93,12 @@ > > static struct drm_mm_node *drm_mm_search_free_generic(const struct drm_mm > *mm, > u64 size, > - unsigned alignment, > + u64 alignment, > unsigned long color, > enum drm_mm_search_flags flags); > static struct drm_mm_node *drm_mm_search_free_in_range_generic(const struct > drm_mm *mm, > u64 size, > - unsigned alignment, > + u64 alignment, > unsigned long color, > u64 start, > u64 end, > @@ -227,7 +227,7 @@ static void drm_mm_interval_tree_add_node(struct > drm_mm_node *hole_node, > > static void drm_mm_insert_helper(struct drm_mm_node *hole_node, > struct drm_mm_node *node, > - u64 size, unsigned alignment, > + u64 size, u64 alignment, > unsigned long color, > enum drm_mm_allocator_flags flags) > { > @@ -246,10 +246,9 @@ static void drm_mm_insert_helper(struct drm_mm_node > *hole_node, > adj_start = adj_end - size; > > if (alignment) { > - u64 tmp = adj_start; > - unsigned rem; > + u64 rem; > > - rem = do_div(tmp, alignment); > + div64_u64_rem(adj_start, alignment, &rem); > if (rem) { > if (flags & DRM_MM_CREATE_TOP) > adj_start -= rem; > @@ -377,7 +376,7 @@ EXPORT_SYMBOL(drm_mm_reserve_node); > * 0 on success, -ENOSPC if there's no suitable hole. > */ > int drm_mm_insert_node_generic(struct drm_mm *mm, struct drm_mm_node *node, > - u64 size, unsigned alignment, > + u64 size, u64 alignment, > unsigned long color, > enum drm_mm_search_flags sflags, > enum drm_mm_allocator_flags aflags) > @@ -399,7 +398,7 @@ EXPORT_SYMBOL(drm_mm_insert_node_generic); > > static void drm_mm_insert_helper_range(struct drm_mm_node *hole_node, > struct drm_mm_node *node, > - u64 size, unsigned alignment, > + u64 size, u64 alignment, > unsigned long color, > u64 start, u64 end, > enum drm_mm_allocator_flags flags) > @@ -424,10 +423,9 @@ static void drm_mm_insert_helper_range(struct > drm_mm_node *hole_node, > adj_start = adj_end - size; > > if (alignment) { > - u64 tmp = adj_start; > - unsigned rem; > + u64 rem; > > - rem = do_div(tmp, alignment); > + div64_u64_rem(adj_start, alignment, &rem); > if (rem) { > if (flags & DRM_MM_CREATE_TOP) > adj_start -= rem; > @@ -483,7 +481,7 @@ static void drm_mm_insert_helper_range(struct drm_mm_node > *hole_node, > * 0 on success, -ENOSPC if there's no suitable hole. > */ > int drm_mm_insert_node_in_range_generic(struct drm_mm *mm, struct > drm_mm_node *node, > - u64 size, unsigned alignment, > + u64 size, u64 alignment, > unsigned long color, > u64 start, u64 end, > enum drm_mm_search_flags sflags, > @@ -550,16 +548,15 @@ void drm_mm_remove_node(struct drm_mm_node *node) > } > EXPORT_SYMBOL(drm_mm_remove_node); > > -static int check_free_hole(u64 start, u64 end, u64 size, unsigned alignment) > +static int check_free_hole(u64 start, u64 end, u64 size, u64 alignment) > { > if (end - start < size) > return 0; > > if (alignment) { > - u64 tmp = start; > - unsigned rem; > + u64 rem; > > - rem = do_div(tmp, alignment); > + div64_u64_rem(start, alignment, &rem); > if (rem) > start += alignment - rem; > } > @@ -569,7 +566,7 @@ static int check_free_hole(u64 start, u64 end, u64 size, > unsigned alignment) > > static struct drm_mm_node *drm_mm_search_free_generic(const struct drm_mm > *mm, > u64 size, > - unsigned alignment, > + u64 alignment, > unsigned long color, > enum drm_mm_search_flags > flags) > { > @@ -611,7 +608,7 @@ static struct drm_mm_node > *drm_mm_search_free_generic(const struct drm_mm *mm, > > static struct drm_mm_node *drm_mm_search_free_in_range_generic(const struct > drm_mm *mm, > u64 size, > - unsigned alignment, > + u64 alignment, > unsigned long color, > u64 start, > u64 end, > @@ -729,7 +726,7 @@ EXPORT_SYMBOL(drm_mm_replace_node); > */ > void drm_mm_init_scan(struct drm_mm *mm, > u64 size, > - unsigned alignment, > + u64 alignment, > unsigned long color) > { > mm->scan_color = color; > @@ -762,7 +759,7 @@ EXPORT_SYMBOL(drm_mm_init_scan); > */ > void drm_mm_init_scan_with_range(struct drm_mm *mm, > u64 size, > - unsigned alignment, > + u64 alignment, > unsigned long color, > u64 start, > u64 end) > diff --git a/include/drm/drm_mm.h b/include/drm/drm_mm.h > index dff4c507d2c2..dc9710c31a45 100644 > --- a/include/drm/drm_mm.h > +++ b/include/drm/drm_mm.h > @@ -92,12 +92,12 @@ struct drm_mm { > struct rb_root interval_tree; > > unsigned int scan_check_range : 1; > - unsigned scan_alignment; > + unsigned int scanned_blocks; > unsigned long scan_color; > + u64 scan_alignment; > u64 scan_size; > u64 scan_hit_start; > u64 scan_hit_end; > - unsigned scanned_blocks; > u64 scan_start; > u64 scan_end; > struct drm_mm_node *prev_scanned_node; > @@ -229,7 +229,7 @@ int drm_mm_reserve_node(struct drm_mm *mm, struct > drm_mm_node *node); > int drm_mm_insert_node_generic(struct drm_mm *mm, > struct drm_mm_node *node, > u64 size, > - unsigned alignment, > + u64 alignment, > unsigned long color, > enum drm_mm_search_flags sflags, > enum drm_mm_allocator_flags aflags); > @@ -252,7 +252,7 @@ int drm_mm_insert_node_generic(struct drm_mm *mm, > static inline int drm_mm_insert_node(struct drm_mm *mm, > struct drm_mm_node *node, > u64 size, > - unsigned alignment, > + u64 alignment, > enum drm_mm_search_flags flags) > { > return drm_mm_insert_node_generic(mm, node, size, alignment, 0, flags, > @@ -262,7 +262,7 @@ static inline int drm_mm_insert_node(struct drm_mm *mm, > int drm_mm_insert_node_in_range_generic(struct drm_mm *mm, > struct drm_mm_node *node, > u64 size, > - unsigned alignment, > + u64 alignment, > unsigned long color, > u64 start, > u64 end, > @@ -289,7 +289,7 @@ int drm_mm_insert_node_in_range_generic(struct drm_mm *mm, > static inline int drm_mm_insert_node_in_range(struct drm_mm *mm, > struct drm_mm_node *node, > u64 size, > - unsigned alignment, > + u64 alignment, > u64 start, > u64 end, > enum drm_mm_search_flags flags) > @@ -331,11 +331,11 @@ __drm_mm_interval_first(struct drm_mm *mm, u64 start, > u64 last); > > void drm_mm_init_scan(struct drm_mm *mm, > u64 size, > - unsigned alignment, > + u64 alignment, > unsigned long color); > void drm_mm_init_scan_with_range(struct drm_mm *mm, > u64 size, > - unsigned alignment, > + u64 alignment, > unsigned long color, > u64 start, > u64 end);