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);


Reply via email to