[Intel-gfx] [PATCH i-g-t 18/19] i915: Add gem_exec_balancer

Chris Wilson chris at chris-wilson.co.uk
Tue Mar 12 10:27:48 UTC 2019


Quoting Tvrtko Ursulin (2019-03-12 10:23:12)
> 
> On 08/03/2019 18:11, Chris Wilson wrote:
> > Exercise the in-kernel load balancer checking that we can distribute
> > batches across the set of ctx->engines to avoid load.
> > 
> > Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
> > ---
> >   tests/Makefile.am              |   1 +
> >   tests/Makefile.sources         |   1 +
> >   tests/i915/gem_exec_balancer.c | 627 +++++++++++++++++++++++++++++++++
> >   tests/meson.build              |   7 +
> >   4 files changed, 636 insertions(+)
> >   create mode 100644 tests/i915/gem_exec_balancer.c
> > 
> > diff --git a/tests/Makefile.am b/tests/Makefile.am
> > index 289249b42..68a9c14bf 100644
> > --- a/tests/Makefile.am
> > +++ b/tests/Makefile.am
> > @@ -102,6 +102,7 @@ gem_close_race_LDADD = $(LDADD) -lpthread
> >   gem_ctx_thrash_CFLAGS = $(AM_CFLAGS) $(THREAD_CFLAGS)
> >   gem_ctx_thrash_LDADD = $(LDADD) -lpthread
> >   gem_ctx_sseu_LDADD = $(LDADD) $(top_builddir)/lib/libigt_perf.la
> > +i915_gem_exec_balancer_LDADD = $(LDADD) $(top_builddir)/lib/libigt_perf.la
> >   gem_exec_capture_LDADD = $(LDADD) -lz
> >   gem_exec_parallel_CFLAGS = $(AM_CFLAGS) $(THREAD_CFLAGS)
> >   gem_exec_parallel_LDADD = $(LDADD) -lpthread
> > diff --git a/tests/Makefile.sources b/tests/Makefile.sources
> > index 41e756f15..f6c21a1aa 100644
> > --- a/tests/Makefile.sources
> > +++ b/tests/Makefile.sources
> > @@ -23,6 +23,7 @@ TESTS_progs = \
> >       drm_read \
> >       i915/gem_ctx_engines \
> >       i915/gem_ctx_shared \
> > +     i915/gem_exec_balancer \
> >       kms_3d \
> >       kms_addfb_basic \
> >       kms_atomic \
> > diff --git a/tests/i915/gem_exec_balancer.c b/tests/i915/gem_exec_balancer.c
> > new file mode 100644
> > index 000000000..d9fdffe67
> > --- /dev/null
> > +++ b/tests/i915/gem_exec_balancer.c
> > @@ -0,0 +1,627 @@
> > +/*
> > + * Copyright © 2018 Intel Corporation
> > + *
> > + * Permission is hereby granted, free of charge, to any person obtaining a
> > + * copy of this software and associated documentation files (the "Software"),
> > + * to deal in the Software without restriction, including without limitation
> > + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> > + * and/or sell copies of the Software, and to permit persons to whom the
> > + * Software is furnished to do so, subject to the following conditions:
> > + *
> > + * The above copyright notice and this permission notice (including the next
> > + * paragraph) shall be included in all copies or substantial portions of the
> > + * Software.
> > + *
> > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> > + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
> > + * IN THE SOFTWARE.
> > + */
> > +
> > +#include <sched.h>
> > +
> > +#include "igt.h"
> > +#include "igt_perf.h"
> > +#include "i915/gem_ring.h"
> > +#include "sw_sync.h"
> > +
> > +IGT_TEST_DESCRIPTION("Exercise in-kernel load-balancing");
> > +
> > +struct class_instance {
> > +     uint16_t class;
> > +     uint16_t instance;
> > +};
> > +#define INSTANCE_COUNT (1 << I915_PMU_SAMPLE_INSTANCE_BITS)
> > +
> > +static bool has_class_instance(int i915, uint16_t class, uint16_t instance)
> > +{
> > +     int fd;
> > +
> > +     fd = perf_i915_open(I915_PMU_ENGINE_BUSY(class, instance));
> > +     if (fd != -1) {
> > +             close(fd);
> > +             return true;
> > +     }
> > +
> > +     return false;
> > +}
> > +
> > +static struct class_instance *
> > +list_engines(int i915, uint32_t class_mask, unsigned int *out)
> > +{
> > +     unsigned int count = 0, size = 64;
> > +     struct class_instance *engines;
> > +
> > +     engines = malloc(size * sizeof(*engines));
> > +     if (!engines) {
> > +             *out = 0;
> > +             return NULL;
> > +     }
> > +
> > +     for (enum drm_i915_gem_engine_class class = I915_ENGINE_CLASS_RENDER;
> > +          class_mask;
> > +          class++, class_mask >>= 1) {
> > +             if (!(class_mask & 1))
> > +                     continue;
> > +
> > +             for (unsigned int instance = 0;
> > +                  instance < INSTANCE_COUNT;
> > +                  instance++) {
> > +                  if (!has_class_instance(i915, class, instance))
> > +                          continue;
> > +
> > +                     if (count == size) {
> > +                             struct class_instance *e;
> > +
> > +                             size *= 2;
> > +                             e = realloc(engines, size*sizeof(*engines));
> > +                             if (!e) {
> > +                                     *out = count;
> > +                                     return engines;
> > +                             }
> > +
> > +                             engines = e;
> > +                     }
> > +
> > +                     engines[count++] = (struct class_instance){
> > +                             .class = class,
> > +                             .instance = instance,
> > +                     };
> > +             }
> > +     }
> > +
> > +     if (!count) {
> > +             free(engines);
> > +             engines = NULL;
> > +     }
> > +
> > +     *out = count;
> > +     return engines;
> > +}
> > +
> > +static int __set_load_balancer(int i915, uint32_t ctx,
> > +                            const struct class_instance *ci,
> > +                            unsigned int count)
> > +{
> > +     struct i915_context_engines_load_balance balancer = {
> > +             { .name = I915_CONTEXT_ENGINES_EXT_LOAD_BALANCE },
> > +             .engines_mask = ~0ull,
> > +     };
> > +     I915_DEFINE_CONTEXT_PARAM_ENGINES(engines, count + 1);
> > +     struct drm_i915_gem_context_param p = {
> > +             .ctx_id = ctx,
> > +             .param = I915_CONTEXT_PARAM_ENGINES,
> > +             .size = sizeof(&engines),
> 
> sizeof(engines)

Ta. Don't look at the bonding test -- that still has all the +1 offset
baked in. ;)
-Chris


More information about the Intel-gfx mailing list