[Intel-gfx] [PATCH v2 2/2] Revert "drm/i915/lmem: Limit block size to 4G"

Matthew Auld matthew.william.auld at gmail.com
Wed Dec 2 16:40:36 UTC 2020


On Wed, 2 Dec 2020 at 15:51, Chris Wilson <chris at chris-wilson.co.uk> wrote:
>
> Mixing I915_ALLOC_CONTIGUOUS and I915_ALLOC_MAX_SEGMENT_SIZE fared
> badly. The two directives conflict, with the contiguous request setting
> the min_order to the full size of the object, and the max-segment-size
> setting the max_order to the limit of the DMA mapper, resulting in a
> situation where max_order < min_order, causing our sanity checks to
> fail.
>
> Instead of limiting the buddy block size, in the previous patch we split
> the oversized buddy into multiple scatterlist elements.
>
> Fixes: d2cf0125d4a1 ("drm/i915/lmem: Limit block size to 4G")
> Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
> Cc: Niranjana Vishwanathapura <niranjana.vishwanathapura at intel.com>
> Cc: Matthew Auld <matthew.auld at intel.com>
> ---
>  drivers/gpu/drm/i915/gem/i915_gem_region.c    |  2 +-
>  drivers/gpu/drm/i915/intel_memory_region.c    | 18 +---------
>  drivers/gpu/drm/i915/intel_memory_region.h    |  5 ++-
>  .../drm/i915/selftests/intel_memory_region.c  | 34 ++++++++++++-------
>  4 files changed, 26 insertions(+), 33 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_region.c b/drivers/gpu/drm/i915/gem/i915_gem_region.c
> index edb84072f979..e605cccd52f4 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_region.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_region.c
> @@ -43,7 +43,7 @@ i915_gem_object_get_pages_buddy(struct drm_i915_gem_object *obj)
>                 return -ENOMEM;
>         }
>
> -       flags = I915_ALLOC_MIN_PAGE_SIZE | I915_ALLOC_MAX_SEGMENT_SIZE;
> +       flags = I915_ALLOC_MIN_PAGE_SIZE;
>         if (obj->flags & I915_BO_ALLOC_CONTIGUOUS)
>                 flags |= I915_ALLOC_CONTIGUOUS;
>
> diff --git a/drivers/gpu/drm/i915/intel_memory_region.c b/drivers/gpu/drm/i915/intel_memory_region.c
> index ae36e2f6d6e3..b326993a1026 100644
> --- a/drivers/gpu/drm/i915/intel_memory_region.c
> +++ b/drivers/gpu/drm/i915/intel_memory_region.c
> @@ -72,7 +72,6 @@ __intel_memory_region_get_pages_buddy(struct intel_memory_region *mem,
>                                       struct list_head *blocks)
>  {
>         unsigned int min_order = 0;
> -       unsigned int max_order;
>         unsigned long n_pages;
>
>         GEM_BUG_ON(!IS_ALIGNED(size, mem->mm.chunk_size));
> @@ -93,28 +92,13 @@ __intel_memory_region_get_pages_buddy(struct intel_memory_region *mem,
>
>         n_pages = size >> ilog2(mem->mm.chunk_size);
>
> -       /*
> -        * If we going to feed this into an sg list we should limit the block
> -        * sizes such that we don't exceed the i915_sg_segment_size().
> -        */
> -       if (flags & I915_ALLOC_MAX_SEGMENT_SIZE) {
> -               unsigned int max_segment = i915_sg_segment_size();
> -
> -               if (GEM_WARN_ON(max_segment < mem->mm.chunk_size))
> -                       max_order = 0;
> -               else
> -                       max_order = ilog2(max_segment) - ilog2(mem->mm.chunk_size);
> -       } else {
> -               max_order = mem->mm.max_order;
> -       }
> -
>         mutex_lock(&mem->mm_lock);
>
>         do {
>                 struct i915_buddy_block *block;
>                 unsigned int order;
>
> -               order = min_t(u32, fls(n_pages) - 1, max_order);
> +               order = fls(n_pages) - 1;
>                 GEM_BUG_ON(order > mem->mm.max_order);
>                 GEM_BUG_ON(order < min_order);
>
> diff --git a/drivers/gpu/drm/i915/intel_memory_region.h b/drivers/gpu/drm/i915/intel_memory_region.h
> index 5fb9bcf86b97..232490d89a83 100644
> --- a/drivers/gpu/drm/i915/intel_memory_region.h
> +++ b/drivers/gpu/drm/i915/intel_memory_region.h
> @@ -44,9 +44,8 @@ enum intel_region_id {
>  #define MEMORY_TYPE_FROM_REGION(r) (ilog2((r) >> INTEL_MEMORY_TYPE_SHIFT))
>  #define MEMORY_INSTANCE_FROM_REGION(r) (ilog2((r) & 0xffff))
>
> -#define I915_ALLOC_MIN_PAGE_SIZE       BIT(0)
> -#define I915_ALLOC_CONTIGUOUS          BIT(1)
> -#define I915_ALLOC_MAX_SEGMENT_SIZE    BIT(2)
> +#define I915_ALLOC_MIN_PAGE_SIZE  BIT(0)
> +#define I915_ALLOC_CONTIGUOUS     BIT(1)
>
>  #define for_each_memory_region(mr, i915, id) \
>         for (id = 0; id < ARRAY_SIZE((i915)->mm.regions); id++) \
> diff --git a/drivers/gpu/drm/i915/selftests/intel_memory_region.c b/drivers/gpu/drm/i915/selftests/intel_memory_region.c
> index 7c02a0c16fc1..1650f8d9c026 100644
> --- a/drivers/gpu/drm/i915/selftests/intel_memory_region.c
> +++ b/drivers/gpu/drm/i915/selftests/intel_memory_region.c
> @@ -356,21 +356,21 @@ static int igt_mock_splintered_region(void *arg)
>
>  static int igt_mock_max_segment(void *arg)
>  {
> +       const unsigned int max_segment = i915_sg_segment_size();
>         struct intel_memory_region *mem = arg;
>         struct drm_i915_private *i915 = mem->i915;
>         struct drm_i915_gem_object *obj;
>         struct i915_buddy_block *block;
> +       struct scatterlist *sg;
>         LIST_HEAD(objects);
>         u64 size;
>         int err = 0;
>
>         /*
> -        * The size of block are only limited by the largest power-of-two that
> -        * will fit in the region size, but to construct an object we also
> -        * require feeding it into an sg list, where the upper limit of the sg
> -        * entry is at most UINT_MAX, therefore when allocating with
> -        * I915_ALLOC_MAX_SEGMENT_SIZE we shouldn't see blocks larger than
> -        * i915_sg_segment_size().
> +        * While we may create very large contiguous blocks, we may need
> +        * to break those down for consumption elsewhere. In particular,
> +        * dma-mapping with scatterlist elements have an implicit limit of
> +        * UINT_MAX on each element.
>          */
>
>         size = SZ_8G;
> @@ -384,13 +384,23 @@ static int igt_mock_max_segment(void *arg)
>                 goto out_put;
>         }
>
> +       err = -EINVAL;
>         list_for_each_entry(block, &obj->mm.blocks, link) {
> -               if (i915_buddy_block_size(&mem->mm, block) > i915_sg_segment_size()) {
> -                       pr_err("%s found block size(%llu) larger than max sg_segment_size(%u)",
> -                              __func__,
> -                              i915_buddy_block_size(&mem->mm, block),
> -                              i915_sg_segment_size());
> -                       err = -EINVAL;
> +               if (i915_buddy_block_size(&mem->mm, block) > max_segment) {
> +                       err = 0;
> +                       break;
> +               }
> +       }
> +       if (err) {
> +               pr_err("%s: Failed to create a huge contiguous block\n",
> +                      __func__);
> +               goto out_close;
> +       }
> +
> +       for (sg = obj->mm.pages->sgl; sg; sg = sg_next(sg)) {
> +               if (sg->length > max_segment) {
> +                       pr_err("%s: Created an oversized scatterlist entry, %u > %u\n",
> +                              __func__, sg->length, max_segment);

err = -EINVAL;

Reviewed-by: Matthew Auld <matthew.auld at intel.com>

>                         goto out_close;
>                 }
>         }
> --
> 2.20.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx


More information about the Intel-gfx mailing list