[Intel-gfx] [PATCH i-g-t] igt/gem_ringfill: Adds ringbuffer full preemption test

Chris Wilson chris at chris-wilson.co.uk
Thu Aug 24 12:22:50 UTC 2017


Quoting MichaƂ Winiarski (2017-08-24 13:13:30)
> > +static void alarm_handler(int sig)
> > +{
> > +}
> > +
> > +static int __execbuf(int fd, struct drm_i915_gem_execbuffer2 *execbuf)
> > +{
> > +     return ioctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, execbuf);
> > +}
> > +
> 
> So... __gem_execbuf?

__gem_execbuf() eats EINTR, which we need to break out of the loop.

> 
> >  static int __ctx_set_priority(int fd, uint32_t ctx, int prio)
> >  {
> >       struct local_i915_gem_context_param param;
> > @@ -659,6 +673,95 @@ static bool has_scheduler(int fd)
> >       return has > 0;
> >  }
> >  
> > +static void bind_to_cpu(int cpu)
> > +{
> > +     const int ncpus = sysconf(_SC_NPROCESSORS_ONLN);
> > +     cpu_set_t allowed;
> > +
> > +     CPU_ZERO(&allowed);
> > +     CPU_SET(cpu % ncpus, &allowed);
> > +     igt_assert(sched_setaffinity(getpid(), sizeof(cpu_set_t), &allowed) == 0);
> 
> We need to make sure that the child is not running before parent blocks in the
> last execbuf - meaning that we probably want to make the parent (but not the
> child) realtime. (see email from Chris)
> 
> > +}
> > +
> > +static void setup_timer(int timeout)
> > +{
> > +     struct itimerval itv;
> > +     struct sigaction sa = { .sa_handler = alarm_handler };
> > +
> > +     sigaction(SIGALRM, &sa, NULL);
> > +     itv.it_interval.tv_sec = 0;
> > +     itv.it_interval.tv_usec = 100;
> 
> Using this interval doesn't allow fork to complete on my machine.

(Because it gets caught in EINTR hell, I presume.)

> But we should probably disable the timer across fork anyway.
> 
> > +     itv.it_value.tv_sec = 0;
> > +     itv.it_value.tv_usec = timeout * 1000;
> > +     setitimer(ITIMER_REAL, &itv, NULL);
> > +}
> > +
> > +/*
> > + * This test checks that is possible for a high priority request to trigger a
> > + * preemption if another context has filled its ringbuffer.
> > + * The aim of the test is to make sure that high priority requests cannot be
> > + * stalled by low priority tasks.
> > + * */
> > +static void preempt_while_ringbuffer_full(int fd, uint32_t engine)
> > +{
> > +     uint32_t hp_fd;
> > +     uint32_t hp_ctx, lp_ctx;
> > +     struct drm_i915_gem_exec_object2 obj, hp_obj;
> > +     struct drm_i915_gem_execbuffer2 execbuf;
> > +
> > +     const unsigned timeout = 10; /*ms*/
> > +     const uint32_t bbe = MI_BATCH_BUFFER_END;
> > +
> > +     hp_fd = drm_open_driver(DRIVER_INTEL);
> 
> Why the extra FD if we're going to use non-default contexts anyway?

I actually suggested the extra isolation. It depends on tracking down
all permutations and possible mutex interactions. For starters, we don't
need the extra fd as we can demonstrate the inversion just with two
contexts. But we need to design a framework to find all of these before
the client/user does.
-Chris


More information about the Intel-gfx mailing list