Am 12.12.2016 um 12:53 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>
Nice, we have a few things which could use an alignment above 4GB as well. Patch is Reviewed-by: Christian König <christian.koenig at amd.com>. > --- > drivers/gpu/drm/drm_mm.c | 37 > +++++++++++++++------------------ > drivers/gpu/drm/selftests/test-drm_mm.c | 2 +- > include/drm/drm_mm.h | 16 +++++++------- > 3 files changed, 26 insertions(+), 29 deletions(-) > > diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c > index 6e0735539545..621a5792a0dd 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; > @@ -376,7 +375,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) > @@ -398,7 +397,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) > @@ -423,10 +422,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; > @@ -482,7 +480,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, > @@ -549,16 +547,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; > } > @@ -568,7 +565,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) > { > @@ -610,7 +607,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, > @@ -728,7 +725,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; > @@ -761,7 +758,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/drivers/gpu/drm/selftests/test-drm_mm.c > b/drivers/gpu/drm/selftests/test-drm_mm.c > index 02f10d9d1396..cad42919f15f 100644 > --- a/drivers/gpu/drm/selftests/test-drm_mm.c > +++ b/drivers/gpu/drm/selftests/test-drm_mm.c > @@ -775,7 +775,7 @@ static int igt_align64(void *ignored) > > static void show_scan(const struct drm_mm *scan) > { > - pr_info("scan: hit [%llx, %llx], size=%lld, align=%d, color=%ld\n", > + pr_info("scan: hit [%llx, %llx], size=%lld, align=%lld, color=%ld\n", > scan->scan_hit_start, scan->scan_hit_end, > scan->scan_size, scan->scan_alignment, scan->scan_color); > } > diff --git a/include/drm/drm_mm.h b/include/drm/drm_mm.h > index 8faa28ad97b3..e3322f92633e 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; > @@ -242,7 +242,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); > @@ -265,7 +265,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, > @@ -275,7 +275,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, > @@ -302,7 +302,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) > @@ -344,11 +344,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);