[Intel-gfx] [PATCH] [v2] drm/i915: Make semaphore updates more precise

Ben Widawsky ben at bwidawsk.net
Tue Feb 11 22:50:09 CET 2014


On Tue, Feb 11, 2014 at 10:53:40PM +0200, Ville Syrjälä wrote:
> On Tue, Feb 11, 2014 at 12:20:42PM -0800, Ben Widawsky wrote:
> > With the ring mask we now have an easy way to know the number of rings
> > in the system, and therefore can accurately predict the number of dwords
> > to emit for semaphore signalling. This was not possible (easily)
> > previously.
> > 
> > There should be no functional impact, simply fewer instructions emitted.
> > 
> > While we're here, simply do the round up to 2 instead of the fancier
> > rounding we did before, which rounding up per mbox, ie 4. This also
> > allows us to drop the unnecessary MI_NOOP, so not really 4, 3.
> > 
> > v2: Use 3 dwords instead of 4 (Ville)
> > Do the proper calculation to get the number of dwords to emit (Ville)
> > Conditionally set .sync_to when semaphores are enabled (Ville)
> > 
> > Signed-off-by: Ben Widawsky <ben at bwidawsk.net>
> 
> Yeah looks OK now. Well, assuming we don't keep going when we fail to
> init one or more rings, because in that case the loop would fail to emit
> all the dwords it was supposed to.
> 

Yeah. I don't think this is ever the behavior we should aim form.
Though more generally though I feel our code chickens out too often. If
the HW is supposed to support it, I'd rather get a bug report than try
to limp along.

> IIRC the rest of the patches looked good up to 05/11. So for patches
> 01-05:
> Reviewed-by: Ville Syrjälä <ville.syrjala at linux.intel.com>

Thanks.

> 
> > ---
> >  drivers/gpu/drm/i915/intel_ringbuffer.c | 55 ++++++++++++++++++---------------
> >  1 file changed, 30 insertions(+), 25 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
> > index 70f7190..483684f 100644
> > --- a/drivers/gpu/drm/i915/intel_ringbuffer.c
> > +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
> > @@ -635,24 +635,19 @@ static void render_ring_cleanup(struct intel_ring_buffer *ring)
> >  static int gen6_signal(struct intel_ring_buffer *signaller,
> >  		       unsigned int num_dwords)
> >  {
> > +#define MBOX_UPDATE_DWORDS 3
> >  	struct drm_device *dev = signaller->dev;
> >  	struct drm_i915_private *dev_priv = dev->dev_private;
> >  	struct intel_ring_buffer *useless;
> > -	int i, ret;
> > +	int i, ret, num_rings;
> >  
> > -	/* NB: In order to be able to do semaphore MBOX updates for varying
> > -	 * number of rings, it's easiest if we round up each individual update
> > -	 * to a multiple of 2 (since ring updates must always be a multiple of
> > -	 * 2) even though the actual update only requires 3 dwords.
> > -	 */
> > -#define MBOX_UPDATE_DWORDS 4
> > -	if (i915_semaphore_is_enabled(dev))
> > -		num_dwords += ((I915_NUM_RINGS-1) * MBOX_UPDATE_DWORDS);
> > +	num_rings = hweight_long(INTEL_INFO(dev)->ring_mask);
> > +	num_dwords += round_up((num_rings-1) * MBOX_UPDATE_DWORDS, 2);
> > +#undef MBOX_UPDATE_DWORDS
> >  
> >  	ret = intel_ring_begin(signaller, num_dwords);
> >  	if (ret)
> >  		return ret;
> > -#undef MBOX_UPDATE_DWORDS
> >  
> >  	for_each_ring(useless, dev_priv, i) {
> >  		u32 mbox_reg = signaller->semaphore.signal_mbox[i];
> > @@ -660,15 +655,13 @@ static int gen6_signal(struct intel_ring_buffer *signaller,
> >  			intel_ring_emit(signaller, MI_LOAD_REGISTER_IMM(1));
> >  			intel_ring_emit(signaller, mbox_reg);
> >  			intel_ring_emit(signaller, signaller->outstanding_lazy_seqno);
> > -			intel_ring_emit(signaller, MI_NOOP);
> > -		} else {
> > -			intel_ring_emit(signaller, MI_NOOP);
> > -			intel_ring_emit(signaller, MI_NOOP);
> > -			intel_ring_emit(signaller, MI_NOOP);
> > -			intel_ring_emit(signaller, MI_NOOP);
> >  		}
> >  	}
> >  
> > +	/* If num_dwords was rounded, make sure the tail pointer is correct */
> > +	if (num_rings % 2 == 0)
> > +		intel_ring_emit(signaller, MI_NOOP);
> > +
> >  	return 0;
> >  }
> >  
> > @@ -686,7 +679,11 @@ gen6_add_request(struct intel_ring_buffer *ring)
> >  {
> >  	int ret;
> >  
> > -	ret = ring->semaphore.signal(ring, 4);
> > +	if (ring->semaphore.signal)
> > +		ret = ring->semaphore.signal(ring, 4);
> > +	else
> > +		ret = intel_ring_begin(ring, 4);
> > +
> >  	if (ret)
> >  		return ret;
> >  
> > @@ -1880,8 +1877,10 @@ int intel_init_render_ring_buffer(struct drm_device *dev)
> >  		ring->irq_enable_mask = GT_RENDER_USER_INTERRUPT;
> >  		ring->get_seqno = gen6_ring_get_seqno;
> >  		ring->set_seqno = ring_set_seqno;
> > -		ring->semaphore.sync_to = gen6_ring_sync;
> > -		ring->semaphore.signal = gen6_signal;
> > +		if (i915_semaphore_is_enabled(dev)) {
> > +			ring->semaphore.sync_to = gen6_ring_sync;
> > +			ring->semaphore.signal = gen6_signal;
> > +		}
> >  		ring->semaphore.mbox[RCS] = MI_SEMAPHORE_SYNC_INVALID;
> >  		ring->semaphore.mbox[VCS] = MI_SEMAPHORE_SYNC_RV;
> >  		ring->semaphore.mbox[BCS] = MI_SEMAPHORE_SYNC_RB;
> > @@ -2057,8 +2056,10 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev)
> >  			ring->dispatch_execbuffer =
> >  				gen6_ring_dispatch_execbuffer;
> >  		}
> > -		ring->semaphore.sync_to = gen6_ring_sync;
> > -		ring->semaphore.signal = gen6_signal;
> > +		if (i915_semaphore_is_enabled(dev)) {
> > +			ring->semaphore.sync_to = gen6_ring_sync;
> > +			ring->semaphore.signal = gen6_signal;
> > +		}
> >  		ring->semaphore.mbox[RCS] = MI_SEMAPHORE_SYNC_VR;
> >  		ring->semaphore.mbox[VCS] = MI_SEMAPHORE_SYNC_INVALID;
> >  		ring->semaphore.mbox[BCS] = MI_SEMAPHORE_SYNC_VB;
> > @@ -2115,8 +2116,10 @@ int intel_init_blt_ring_buffer(struct drm_device *dev)
> >  		ring->irq_put = gen6_ring_put_irq;
> >  		ring->dispatch_execbuffer = gen6_ring_dispatch_execbuffer;
> >  	}
> > -	ring->semaphore.sync_to = gen6_ring_sync;
> > -	ring->semaphore.signal = gen6_signal;
> > +	if (i915_semaphore_is_enabled(dev)) {
> > +		ring->semaphore.signal = gen6_signal;
> > +		ring->semaphore.sync_to = gen6_ring_sync;
> > +	}
> >  	ring->semaphore.mbox[RCS] = MI_SEMAPHORE_SYNC_BR;
> >  	ring->semaphore.mbox[VCS] = MI_SEMAPHORE_SYNC_BV;
> >  	ring->semaphore.mbox[BCS] = MI_SEMAPHORE_SYNC_INVALID;
> > @@ -2157,8 +2160,10 @@ int intel_init_vebox_ring_buffer(struct drm_device *dev)
> >  		ring->irq_put = hsw_vebox_put_irq;
> >  		ring->dispatch_execbuffer = gen6_ring_dispatch_execbuffer;
> >  	}
> > -	ring->semaphore.sync_to = gen6_ring_sync;
> > -	ring->semaphore.signal = gen6_signal;
> > +	if (i915_semaphore_is_enabled(dev)) {
> > +		ring->semaphore.sync_to = gen6_ring_sync;
> > +		ring->semaphore.signal = gen6_signal;
> > +	}
> >  	ring->semaphore.mbox[RCS] = MI_SEMAPHORE_SYNC_VER;
> >  	ring->semaphore.mbox[VCS] = MI_SEMAPHORE_SYNC_VEV;
> >  	ring->semaphore.mbox[BCS] = MI_SEMAPHORE_SYNC_VEB;
> > -- 
> > 1.8.5.4
> 
> -- 
> Ville Syrjälä
> Intel OTC

-- 
Ben Widawsky, Intel Open Source Technology Center



More information about the Intel-gfx mailing list