[igt-dev] [PATCH i-g-t v18 18/31] tests/gem_softpin: Verify allocator and execbuf pair work together

Zbigniew Kempczyński zbigniew.kempczynski at intel.com
Mon Feb 1 08:52:09 UTC 2021


On Fri, Jan 29, 2021 at 04:03:46PM +0000, Chris Wilson wrote:
> Quoting Zbigniew Kempczyński (2021-01-29 14:44:41)
> > Exercise objects offsets produced by the allocator for execbuf
> > are valid and no EINVAL/ENOSPC occurs. Check it works properly
> > also for multiprocess allocations/execbufs for same context.
> > As we're in full-ppgtt we disable softpin to verify offsets produced
> > by the allocator are valid and kernel doesn't want to relocate them.
> > 
> > Add allocator-basic and allocator-basic-reserve to BAT.
> > 
> > Signed-off-by: Zbigniew Kempczyński <zbigniew.kempczynski at intel.com>
> > Cc: Chris Wilson <chris at chris-wilson.co.uk>
> > ---
> >  tests/i915/gem_softpin.c              | 179 ++++++++++++++++++++++++++
> >  tests/intel-ci/fast-feedback.testlist |   2 +
> >  2 files changed, 181 insertions(+)
> > 
> > diff --git a/tests/i915/gem_softpin.c b/tests/i915/gem_softpin.c
> > index aba060a42..c87de212d 100644
> > --- a/tests/i915/gem_softpin.c
> > +++ b/tests/i915/gem_softpin.c
> > @@ -28,6 +28,7 @@
> >  
> >  #include "i915/gem.h"
> >  #include "igt.h"
> > +#include "intel_allocator.h"
> >  
> >  #define EXEC_OBJECT_PINNED     (1<<4)
> >  #define EXEC_OBJECT_SUPPORTS_48B_ADDRESS (1<<3)
> > @@ -697,6 +698,169 @@ static void test_noreloc(int fd, enum sleep sleep, unsigned flags)
> >                 gem_close(fd, object[i].handle);
> >  }
> >  
> > +static void __reserve(uint64_t ahnd, int i915, bool pinned,
> > +                     struct drm_i915_gem_exec_object2 *objects,
> > +                     int num_obj, uint64_t size)
> > +{
> > +       uint64_t gtt = gem_aperture_size(i915);
> > +       unsigned int flags;
> > +       int i;
> > +
> > +       igt_assert(num_obj > 1);
> > +
> > +       flags = EXEC_OBJECT_SUPPORTS_48B_ADDRESS;
> > +       if (pinned)
> > +               flags |= EXEC_OBJECT_PINNED;
> > +
> > +       memset(objects, 0, sizeof(objects) * num_obj);
> > +
> > +       for (i = 0; i < num_obj; i++) {
> > +               objects[i].handle = gem_create(i915, size);
> > +               if (i < num_obj/2)
> > +                       objects[i].offset = i * size;
> > +               else
> > +                       objects[i].offset = gtt - (i + 1 - num_obj/2) * size;
> > +               objects[i].flags = flags;
> > +
> > +               intel_allocator_reserve(ahnd, objects[i].handle,
> > +                                       size, objects[i].offset);
> > +               igt_debug("Reserve i: %d, handle: %u, offset: %llx\n", i,
> > +                         objects[i].handle, (long long) objects[i].offset);
> > +       }
> > +}
> > +
> > +static void __unreserve(uint64_t ahnd, int i915,
> > +                       struct drm_i915_gem_exec_object2 *objects,
> > +                       int num_obj, uint64_t size)
> > +{
> > +       int i;
> > +
> > +       for (i = 0; i < num_obj; i++) {
> > +               intel_allocator_unreserve(ahnd, objects[i].handle,
> > +                                         size, objects[i].offset);
> > +               igt_debug("Unreserve i: %d, handle: %u, offset: %llx\n", i,
> > +                         objects[i].handle, (long long) objects[i].offset);
> > +               gem_close(i915, objects[i].handle);
> > +       }
> > +}
> > +
> > +static void __exec_using_allocator(uint64_t ahnd, int i915, int num_obj,
> > +                                  bool pinned)
> > +{
> > +       const uint32_t bbe = MI_BATCH_BUFFER_END;
> > +       struct drm_i915_gem_execbuffer2 execbuf;
> > +       struct drm_i915_gem_exec_object2 object[num_obj];
> > +       uint64_t stored_offsets[num_obj];
> > +       unsigned int flags;
> > +       uint64_t sz = 4096;
> > +       int i;
> > +
> > +       igt_assert(num_obj > 10);
> > +
> > +       flags = EXEC_OBJECT_SUPPORTS_48B_ADDRESS;
> > +       if (pinned)
> > +               flags |= EXEC_OBJECT_PINNED;
> > +
> > +       memset(object, 0, sizeof(object));
> > +
> > +       for (i = 0; i < num_obj; i++) {
> > +               sz = (rand() % 15 + 1) * 4096;
> > +               if (i == num_obj - 1)
> > +                       sz = 4096;
> > +               object[i].handle = gem_create(i915, sz);
> > +               object[i].offset =
> > +                       intel_allocator_alloc(ahnd, object[i].handle, sz, 0);
> > +       }
> > +       gem_write(i915, object[--i].handle, 0, &bbe, sizeof(bbe));
> > +
> > +       for (i = 0; i < num_obj; i++) {
> > +               object[i].flags = flags;
> > +               object[i].offset = gen8_canonical_addr(object[i].offset);
> > +               stored_offsets[i] = object[i].offset;
> > +       }
> > +
> > +       memset(&execbuf, 0, sizeof(execbuf));
> > +       execbuf.buffers_ptr = to_user_pointer(object);
> > +       execbuf.buffer_count = num_obj;
> > +       gem_execbuf(i915, &execbuf);
> > +
> > +       for (i = 0; i < num_obj; i++) {
> > +               igt_assert(intel_allocator_free(ahnd, object[i].handle));
> > +               gem_close(i915, object[i].handle);
> > +       }
> > +
> > +       /* Check kernel will keep offsets even if pinned is not set. */
> > +       for (i = 0; i < num_obj; i++)
> > +               igt_assert_eq_u64(stored_offsets[i], object[i].offset);
> > +}
> > +
> > +static void test_allocator_basic(int fd, bool reserve)
> > +{
> > +       const int num_obj = 257, num_reserved = 8;
> > +       struct drm_i915_gem_exec_object2 objects[num_reserved];
> > +       uint64_t ahnd, ressize = 4096;
> 
> /* Check that we can place objects at start/end of the GTT using the allocator */
> 
> > +       ahnd = intel_allocator_open(fd, 0, INTEL_ALLOCATOR_SIMPLE);
> > +
> > +       __reserve(ahnd, fd, true, objects, num_reserved, ressize);
> > +       __exec_using_allocator(ahnd, fd, num_obj, true);
> > +       __unreserve(ahnd, fd, objects, num_reserved, ressize);
> > +       igt_assert(intel_allocator_close(ahnd) == true);
> > +}
> > +
> > +static void test_allocator_nopin(int fd, bool reserve)
> > +{
> > +       const int num_obj = 257, num_reserved = 8;
> > +       struct drm_i915_gem_exec_object2 objects[num_reserved];
> > +       uint64_t ahnd, ressize = 4096;
> 
> /*
>  * Check that we can combine manual placement with automatic GTT placement.
>  *
>  * This will also check that we agree with this small sampling of
>  * allocator placements -- that is the given the same restrictions
>  * in execobj[] the kernel does not reject the placement due to overlaps
>  * or invalid addresses.
>  */
> 
> Ok, that covers the basics. Could you do one more as the most simple
> example of using the allocator? Just a very straight forward testcase
> that we can cut'n'paste as the starting point for new tests. Or if one
> of the api_intel_bb is suitable, that'll do.
> 
> Reviewed-by: Chris Wilson <chris at chris-wilson.co.uk>
> -Chris

I agree, two minimal subtests would be useful for copy-paste
(we need one which is using intel-bb, second for handcrafted
execbuf with allocator).

I'll add above comments and add r-b to softpin. 
--
Zbigniew


More information about the igt-dev mailing list