[Intel-gfx] [PATCH 02/22] drm/i915/gtt: Serialise both updates to PDE and our shadow

Chris Wilson chris at chris-wilson.co.uk
Mon Jun 17 10:40:48 UTC 2019


Quoting Matthew Auld (2019-06-17 11:36:36)
> On 17/06/2019 08:18, Chris Wilson wrote:
> > Currently, we perform a locked update of the shadow entry when
> > allocating a page directory entry such that if two clients are
> > concurrently allocating neighbouring ranges we only insert one new entry
> > for the pair of them. However, we also need to serialise both clients
> > wrt to the actual entry in the HW table, or else we may allow one client
> > or even a third client to proceed ahead of the HW write. My handwave
> > before was that under the _pathological_ condition we would see the
> > scratch entry instead of the expected entry, causing a temporary
> > glitch. That starvation condition will eventually show up in practice, so
> > fix it.
> > 
> > The reason for the previous cheat was to avoid having to free the extra
> > allocation while under the spinlock. Now, we keep the extra entry
> > allocated until the end instead.
> > 
> > Fixes: 1d1b5490b91c ("drm/i915/gtt: Replace struct_mutex serialisation for allocation")
> > Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
> > Cc: Matthew Auld <matthew.auld at intel.com>
> > Cc: Mika Kuoppala <mika.kuoppala at intel.com>
> > ---
> 
> [snip]
> 
> >   
> >   static int gen8_preallocate_top_level_pdp(struct i915_ppgtt *ppgtt)
> > @@ -1819,11 +1831,13 @@ static int gen6_alloc_va_range(struct i915_address_space *vm,
> >                              u64 start, u64 length)
> >   {
> >       struct gen6_ppgtt *ppgtt = to_gen6_ppgtt(i915_vm_to_ppgtt(vm));
> > +     struct i915_page_table *alloc = NULL;
> >       struct i915_page_table *pt;
> >       intel_wakeref_t wakeref;
> >       u64 from = start;
> >       unsigned int pde;
> >       bool flush = false;
> > +     int ret;
> 
> ret = 0;

Yeah, originally this kept to the separate exit paths, forgot to fix
after merging.

> >       wakeref = intel_runtime_pm_get(&vm->i915->runtime_pm);
> >   
> > @@ -1832,19 +1846,18 @@ static int gen6_alloc_va_range(struct i915_address_space *vm,
> >               const unsigned int count = gen6_pte_count(start, length);
> >   
> >               if (pt == vm->scratch_pt) {
> > -                     struct i915_page_table *old;
> > -
> >                       spin_unlock(&ppgtt->base.pd.lock);
> >   
> > -                     pt = alloc_pt(vm);
> > +                     pt = alloc;
> 
> We have to reset this, no?

Yes, obviously missed after fixing the pattern for gen6.

> > +                     if (!pt)
> > +                             pt = alloc_pt(vm);
> >                       if (IS_ERR(pt))
> >                               goto unwind_out;
> 
> ret = PTR_ERR();

Sigh.
Thanks,
-Chris


More information about the Intel-gfx mailing list