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@chris-wilson.co.uk Cc: Joonas Lahtinen joonas.lahtinen@linux.intel.com
Reviewed-by: Christian König christian.koenig@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,
static struct drm_mm_node *drm_mm_search_free_in_range_generic(const struct drm_mm *mm, u64 size,u64 alignment, unsigned long color, enum drm_mm_search_flags flags);
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);
if (rem) { if (flags & DRM_MM_CREATE_TOP) adj_start -= rem;div64_u64_rem(adj_start, alignment, &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);
if (rem) { if (flags & DRM_MM_CREATE_TOP) adj_start -= rem;div64_u64_rem(adj_start, alignment, &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);
if (rem) start += alignment - rem; }div64_u64_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,
{ mm->scan_color = color;u64 alignment, unsigned long 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,
{ return drm_mm_insert_node_generic(mm, node, size, alignment, 0, flags,u64 alignment, enum drm_mm_search_flags 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,
void drm_mm_init_scan_with_range(struct drm_mm *mm, u64 size,u64 alignment, unsigned long color);
unsigned alignment,
u64 alignment, unsigned long color, u64 start, u64 end);