diff mbox

[11/18] drm/i915: Record space required for request emission

Message ID 20160914065250.15482-12-chris@chris-wilson.co.uk (mailing list archive)
State New, archived
Headers show

Commit Message

Chris Wilson Sept. 14, 2016, 6:52 a.m. UTC
In the next patch, we will use deferred request emission. That requires
reserving sufficient space in the ringbuffer to emit the request, which
first requires us to know how large the request is.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/i915_gem_request.c |  1 +
 drivers/gpu/drm/i915/intel_lrc.c        |  6 ++++++
 drivers/gpu/drm/i915/intel_ringbuffer.c | 29 +++++++++++++++++++++++++++--
 drivers/gpu/drm/i915/intel_ringbuffer.h |  1 +
 4 files changed, 35 insertions(+), 2 deletions(-)

Comments

Tvrtko Ursulin Sept. 14, 2016, 1:30 p.m. UTC | #1
On 14/09/2016 07:52, Chris Wilson wrote:
> In the next patch, we will use deferred request emission. That requires
> reserving sufficient space in the ringbuffer to emit the request, which
> first requires us to know how large the request is.
>
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> ---
>   drivers/gpu/drm/i915/i915_gem_request.c |  1 +
>   drivers/gpu/drm/i915/intel_lrc.c        |  6 ++++++
>   drivers/gpu/drm/i915/intel_ringbuffer.c | 29 +++++++++++++++++++++++++++--
>   drivers/gpu/drm/i915/intel_ringbuffer.h |  1 +
>   4 files changed, 35 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_gem_request.c b/drivers/gpu/drm/i915/i915_gem_request.c
> index ebc2feba3e50..9a735e2d5aea 100644
> --- a/drivers/gpu/drm/i915/i915_gem_request.c
> +++ b/drivers/gpu/drm/i915/i915_gem_request.c
> @@ -425,6 +425,7 @@ i915_gem_request_alloc(struct intel_engine_cs *engine,
>   	 * away, e.g. because a GPU scheduler has deferred it.
>   	 */
>   	req->reserved_space = MIN_SPACE_FOR_ADD_REQUEST;
> +	GEM_BUG_ON(req->reserved_space < engine->emit_request_sz);
>   
>   	if (i915.enable_execlists)
>   		ret = intel_logical_ring_alloc_request_extras(req);
> diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
> index 00fcf36ba919..7e944a0acc10 100644
> --- a/drivers/gpu/drm/i915/intel_lrc.c
> +++ b/drivers/gpu/drm/i915/intel_lrc.c
> @@ -1572,6 +1572,8 @@ static int gen8_emit_request(struct drm_i915_gem_request *request)
>   	return intel_logical_ring_advance(request);
>   }
>   
> +static const int gen8_emit_request_sz = 6 + WA_TAIL_DWORDS;
> +
>   static int gen8_emit_request_render(struct drm_i915_gem_request *request)
>   {
>   	struct intel_ring *ring = request->ring;
> @@ -1603,6 +1605,8 @@ static int gen8_emit_request_render(struct drm_i915_gem_request *request)
>   	return intel_logical_ring_advance(request);
>   }
>   
> +static const int gen8_emit_request_render_sz = 8 + WA_TAIL_DWORDS;
> +
>   static int gen8_init_rcs_context(struct drm_i915_gem_request *req)
>   {
>   	int ret;
> @@ -1677,6 +1681,7 @@ logical_ring_default_vfuncs(struct intel_engine_cs *engine)
>   	engine->reset_hw = reset_common_ring;
>   	engine->emit_flush = gen8_emit_flush;
>   	engine->emit_request = gen8_emit_request;
> +	engine->emit_request_sz = gen8_emit_request_sz;
>   	engine->submit_request = execlists_submit_request;
>   
>   	engine->irq_enable = gen8_logical_ring_enable_irq;
> @@ -1799,6 +1804,7 @@ int logical_render_ring_init(struct intel_engine_cs *engine)
>   	engine->init_context = gen8_init_rcs_context;
>   	engine->emit_flush = gen8_emit_flush_render;
>   	engine->emit_request = gen8_emit_request_render;
> +	engine->emit_request_sz = gen8_emit_request_render_sz;
>   
>   	ret = intel_engine_create_scratch(engine, 4096);
>   	if (ret)
> diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
> index 597e35c9b699..c8c9ad40fd93 100644
> --- a/drivers/gpu/drm/i915/intel_ringbuffer.c
> +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
> @@ -1405,6 +1405,8 @@ static int i9xx_emit_request(struct drm_i915_gem_request *req)
>   	return 0;
>   }
>   
> +static const int i9xx_emit_request_sz = 4;
> +
>   /**
>    * gen6_sema_emit_request - Update the semaphore mailbox registers
>    *
> @@ -1458,6 +1460,8 @@ static int gen8_render_emit_request(struct drm_i915_gem_request *req)
>   	return 0;
>   }
>   
> +static const int gen8_render_emit_request_sz = 8;
> +
>   /**
>    * intel_ring_sync - sync the waiter to the signaller on seqno
>    *
> @@ -2677,8 +2681,21 @@ static void intel_ring_default_vfuncs(struct drm_i915_private *dev_priv,
>   	engine->reset_hw = reset_ring_common;
>   
>   	engine->emit_request = i9xx_emit_request;
> -	if (i915.semaphores)
> +	engine->emit_request_sz = i9xx_emit_request_sz;
> +	if (i915.semaphores) {
> +		int num_rings;
> +
>   		engine->emit_request = gen6_sema_emit_request;
> +
> +		num_rings = hweight32(INTEL_INFO(dev_priv)->ring_mask) - 1;

You can use INTEL_INFO(dev_priv)->num_rings instead of hweight32.

> +		if (INTEL_GEN(dev_priv) >= 8) {
> +			engine->emit_request_sz += num_rings * 6;
> +		} else {
> +			engine->emit_request_sz += num_rings * 3;
> +			if (num_rings & 1)
> +				engine->emit_request_sz++;
> +		}
> +	}
>   	engine->submit_request = i9xx_submit_request;
>   
>   	if (INTEL_GEN(dev_priv) >= 8)
> @@ -2706,9 +2723,17 @@ int intel_init_render_ring_buffer(struct intel_engine_cs *engine)
>   	if (INTEL_GEN(dev_priv) >= 8) {
>   		engine->init_context = intel_rcs_ctx_init;
>   		engine->emit_request = gen8_render_emit_request;
> +		engine->emit_request_sz = gen8_render_emit_request_sz;
>   		engine->emit_flush = gen8_render_ring_flush;
> -		if (i915.semaphores)
> +		if (i915.semaphores) {
> +			int num_rings;
> +
>   			engine->semaphore.signal = gen8_rcs_signal;
> +
> +			num_rings =
> +				hweight32(INTEL_INFO(dev_priv)->ring_mask) - 1;

Here as well.

> +			engine->emit_request_sz += num_rings * 6;
> +		}
>   	} else if (INTEL_GEN(dev_priv) >= 6) {
>   		engine->init_context = intel_rcs_ctx_init;
>   		engine->emit_flush = gen7_render_ring_flush;
> diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
> index d6f80b3d66b4..47ad19f5441d 100644
> --- a/drivers/gpu/drm/i915/intel_ringbuffer.h
> +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
> @@ -226,6 +226,7 @@ struct intel_engine_cs {
>   #define I915_DISPATCH_PINNED BIT(1)
>   #define I915_DISPATCH_RS     BIT(2)
>   	int		(*emit_request)(struct drm_i915_gem_request *req);
> +	int		emit_request_sz;
>   
>   	/* Pass the request to the hardware queue (e.g. directly into
>   	 * the legacy ringbuffer or to the end of an execlist).

Regards,

Tvrtko
Chris Wilson Sept. 14, 2016, 5:33 p.m. UTC | #2
On Wed, Sep 14, 2016 at 02:30:20PM +0100, Tvrtko Ursulin wrote:
> 
> On 14/09/2016 07:52, Chris Wilson wrote:
> >In the next patch, we will use deferred request emission. That requires
> >reserving sufficient space in the ringbuffer to emit the request, which
> >first requires us to know how large the request is.
> >
> >Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> >---
> >  drivers/gpu/drm/i915/i915_gem_request.c |  1 +
> >  drivers/gpu/drm/i915/intel_lrc.c        |  6 ++++++
> >  drivers/gpu/drm/i915/intel_ringbuffer.c | 29 +++++++++++++++++++++++++++--
> >  drivers/gpu/drm/i915/intel_ringbuffer.h |  1 +
> >  4 files changed, 35 insertions(+), 2 deletions(-)
> >
> >diff --git a/drivers/gpu/drm/i915/i915_gem_request.c b/drivers/gpu/drm/i915/i915_gem_request.c
> >index ebc2feba3e50..9a735e2d5aea 100644
> >--- a/drivers/gpu/drm/i915/i915_gem_request.c
> >+++ b/drivers/gpu/drm/i915/i915_gem_request.c
> >@@ -425,6 +425,7 @@ i915_gem_request_alloc(struct intel_engine_cs *engine,
> >  	 * away, e.g. because a GPU scheduler has deferred it.
> >  	 */
> >  	req->reserved_space = MIN_SPACE_FOR_ADD_REQUEST;
> >+	GEM_BUG_ON(req->reserved_space < engine->emit_request_sz);
> >  	if (i915.enable_execlists)
> >  		ret = intel_logical_ring_alloc_request_extras(req);
> >diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
> >index 00fcf36ba919..7e944a0acc10 100644
> >--- a/drivers/gpu/drm/i915/intel_lrc.c
> >+++ b/drivers/gpu/drm/i915/intel_lrc.c
> >@@ -1572,6 +1572,8 @@ static int gen8_emit_request(struct drm_i915_gem_request *request)
> >  	return intel_logical_ring_advance(request);
> >  }
> >+static const int gen8_emit_request_sz = 6 + WA_TAIL_DWORDS;
> >+
> >  static int gen8_emit_request_render(struct drm_i915_gem_request *request)
> >  {
> >  	struct intel_ring *ring = request->ring;
> >@@ -1603,6 +1605,8 @@ static int gen8_emit_request_render(struct drm_i915_gem_request *request)
> >  	return intel_logical_ring_advance(request);
> >  }
> >+static const int gen8_emit_request_render_sz = 8 + WA_TAIL_DWORDS;
> >+
> >  static int gen8_init_rcs_context(struct drm_i915_gem_request *req)
> >  {
> >  	int ret;
> >@@ -1677,6 +1681,7 @@ logical_ring_default_vfuncs(struct intel_engine_cs *engine)
> >  	engine->reset_hw = reset_common_ring;
> >  	engine->emit_flush = gen8_emit_flush;
> >  	engine->emit_request = gen8_emit_request;
> >+	engine->emit_request_sz = gen8_emit_request_sz;
> >  	engine->submit_request = execlists_submit_request;
> >  	engine->irq_enable = gen8_logical_ring_enable_irq;
> >@@ -1799,6 +1804,7 @@ int logical_render_ring_init(struct intel_engine_cs *engine)
> >  	engine->init_context = gen8_init_rcs_context;
> >  	engine->emit_flush = gen8_emit_flush_render;
> >  	engine->emit_request = gen8_emit_request_render;
> >+	engine->emit_request_sz = gen8_emit_request_render_sz;
> >  	ret = intel_engine_create_scratch(engine, 4096);
> >  	if (ret)
> >diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
> >index 597e35c9b699..c8c9ad40fd93 100644
> >--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
> >+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
> >@@ -1405,6 +1405,8 @@ static int i9xx_emit_request(struct drm_i915_gem_request *req)
> >  	return 0;
> >  }
> >+static const int i9xx_emit_request_sz = 4;
> >+
> >  /**
> >   * gen6_sema_emit_request - Update the semaphore mailbox registers
> >   *
> >@@ -1458,6 +1460,8 @@ static int gen8_render_emit_request(struct drm_i915_gem_request *req)
> >  	return 0;
> >  }
> >+static const int gen8_render_emit_request_sz = 8;
> >+
> >  /**
> >   * intel_ring_sync - sync the waiter to the signaller on seqno
> >   *
> >@@ -2677,8 +2681,21 @@ static void intel_ring_default_vfuncs(struct drm_i915_private *dev_priv,
> >  	engine->reset_hw = reset_ring_common;
> >  	engine->emit_request = i9xx_emit_request;
> >-	if (i915.semaphores)
> >+	engine->emit_request_sz = i9xx_emit_request_sz;
> >+	if (i915.semaphores) {
> >+		int num_rings;
> >+
> >  		engine->emit_request = gen6_sema_emit_request;
> >+
> >+		num_rings = hweight32(INTEL_INFO(dev_priv)->ring_mask) - 1;
> 
> You can use INTEL_INFO(dev_priv)->num_rings instead of hweight32.

I thought info->num_rings was set afterwards? (And num_rings may be an
overestimate here :(
-Chris
Tvrtko Ursulin Sept. 15, 2016, 8:59 a.m. UTC | #3
On 14/09/2016 18:33, Chris Wilson wrote:
> On Wed, Sep 14, 2016 at 02:30:20PM +0100, Tvrtko Ursulin wrote:
>> On 14/09/2016 07:52, Chris Wilson wrote:
>>> In the next patch, we will use deferred request emission. That requires
>>> reserving sufficient space in the ringbuffer to emit the request, which
>>> first requires us to know how large the request is.
>>>
>>> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
>>> ---
>>>   drivers/gpu/drm/i915/i915_gem_request.c |  1 +
>>>   drivers/gpu/drm/i915/intel_lrc.c        |  6 ++++++
>>>   drivers/gpu/drm/i915/intel_ringbuffer.c | 29 +++++++++++++++++++++++++++--
>>>   drivers/gpu/drm/i915/intel_ringbuffer.h |  1 +
>>>   4 files changed, 35 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/i915/i915_gem_request.c b/drivers/gpu/drm/i915/i915_gem_request.c
>>> index ebc2feba3e50..9a735e2d5aea 100644
>>> --- a/drivers/gpu/drm/i915/i915_gem_request.c
>>> +++ b/drivers/gpu/drm/i915/i915_gem_request.c
>>> @@ -425,6 +425,7 @@ i915_gem_request_alloc(struct intel_engine_cs *engine,
>>>   	 * away, e.g. because a GPU scheduler has deferred it.
>>>   	 */
>>>   	req->reserved_space = MIN_SPACE_FOR_ADD_REQUEST;
>>> +	GEM_BUG_ON(req->reserved_space < engine->emit_request_sz);
>>>   	if (i915.enable_execlists)
>>>   		ret = intel_logical_ring_alloc_request_extras(req);
>>> diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
>>> index 00fcf36ba919..7e944a0acc10 100644
>>> --- a/drivers/gpu/drm/i915/intel_lrc.c
>>> +++ b/drivers/gpu/drm/i915/intel_lrc.c
>>> @@ -1572,6 +1572,8 @@ static int gen8_emit_request(struct drm_i915_gem_request *request)
>>>   	return intel_logical_ring_advance(request);
>>>   }
>>> +static const int gen8_emit_request_sz = 6 + WA_TAIL_DWORDS;
>>> +
>>>   static int gen8_emit_request_render(struct drm_i915_gem_request *request)
>>>   {
>>>   	struct intel_ring *ring = request->ring;
>>> @@ -1603,6 +1605,8 @@ static int gen8_emit_request_render(struct drm_i915_gem_request *request)
>>>   	return intel_logical_ring_advance(request);
>>>   }
>>> +static const int gen8_emit_request_render_sz = 8 + WA_TAIL_DWORDS;
>>> +
>>>   static int gen8_init_rcs_context(struct drm_i915_gem_request *req)
>>>   {
>>>   	int ret;
>>> @@ -1677,6 +1681,7 @@ logical_ring_default_vfuncs(struct intel_engine_cs *engine)
>>>   	engine->reset_hw = reset_common_ring;
>>>   	engine->emit_flush = gen8_emit_flush;
>>>   	engine->emit_request = gen8_emit_request;
>>> +	engine->emit_request_sz = gen8_emit_request_sz;
>>>   	engine->submit_request = execlists_submit_request;
>>>   	engine->irq_enable = gen8_logical_ring_enable_irq;
>>> @@ -1799,6 +1804,7 @@ int logical_render_ring_init(struct intel_engine_cs *engine)
>>>   	engine->init_context = gen8_init_rcs_context;
>>>   	engine->emit_flush = gen8_emit_flush_render;
>>>   	engine->emit_request = gen8_emit_request_render;
>>> +	engine->emit_request_sz = gen8_emit_request_render_sz;
>>>   	ret = intel_engine_create_scratch(engine, 4096);
>>>   	if (ret)
>>> diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
>>> index 597e35c9b699..c8c9ad40fd93 100644
>>> --- a/drivers/gpu/drm/i915/intel_ringbuffer.c
>>> +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
>>> @@ -1405,6 +1405,8 @@ static int i9xx_emit_request(struct drm_i915_gem_request *req)
>>>   	return 0;
>>>   }
>>> +static const int i9xx_emit_request_sz = 4;
>>> +
>>>   /**
>>>    * gen6_sema_emit_request - Update the semaphore mailbox registers
>>>    *
>>> @@ -1458,6 +1460,8 @@ static int gen8_render_emit_request(struct drm_i915_gem_request *req)
>>>   	return 0;
>>>   }
>>> +static const int gen8_render_emit_request_sz = 8;
>>> +
>>>   /**
>>>    * intel_ring_sync - sync the waiter to the signaller on seqno
>>>    *
>>> @@ -2677,8 +2681,21 @@ static void intel_ring_default_vfuncs(struct drm_i915_private *dev_priv,
>>>   	engine->reset_hw = reset_ring_common;
>>>   	engine->emit_request = i9xx_emit_request;
>>> -	if (i915.semaphores)
>>> +	engine->emit_request_sz = i9xx_emit_request_sz;
>>> +	if (i915.semaphores) {
>>> +		int num_rings;
>>> +
>>>   		engine->emit_request = gen6_sema_emit_request;
>>> +
>>> +		num_rings = hweight32(INTEL_INFO(dev_priv)->ring_mask) - 1;
>> You can use INTEL_INFO(dev_priv)->num_rings instead of hweight32.
> I thought info->num_rings was set afterwards? (And num_rings may be an
> overestimate here :(

You are correct, my oversight. Maybe it should have been num_rings and 
num_initialized_rings.

Regards,

Tvrtko
Joonas Lahtinen Sept. 19, 2016, 10:47 a.m. UTC | #4
On ke, 2016-09-14 at 07:52 +0100, Chris Wilson wrote:
> @@ -1572,6 +1572,8 @@ static int gen8_emit_request(struct drm_i915_gem_request *request)
>  	return intel_logical_ring_advance(request);
>  }
>  
> +static const int gen8_emit_request_sz = 6 + WA_TAIL_DWORDS;

Could argue these to be #define by current convention.

> @@ -1677,6 +1681,7 @@ logical_ring_default_vfuncs(struct intel_engine_cs *engine)
>  	engine->reset_hw = reset_common_ring;
>  	engine->emit_flush = gen8_emit_flush;
>  	engine->emit_request = gen8_emit_request;
> +	engine->emit_request_sz = gen8_emit_request_sz;

This assignment would then stand out better too, now it looks like a
bunch of function assignments.

> @@ -2677,8 +2681,21 @@ static void intel_ring_default_vfuncs(struct drm_i915_private *dev_priv,
>  	engine->reset_hw = reset_ring_common;
>  
>  	engine->emit_request = i9xx_emit_request;
> -	if (i915.semaphores)
> +	engine->emit_request_sz = i9xx_emit_request_sz;
> +	if (i915.semaphores) {
> +		int num_rings;

'initialized_rings' to differentiate as suggested by Tvrtko too.

> +
>  		engine->emit_request = gen6_sema_emit_request;
> +
> +		num_rings = hweight32(INTEL_INFO(dev_priv)->ring_mask) - 1;
> +		if (INTEL_GEN(dev_priv) >= 8) {
> +			engine->emit_request_sz += num_rings * 6;
> +		} else {
> +			engine->emit_request_sz += num_rings * 3;
> +			if (num_rings & 1)
> +				engine->emit_request_sz++;

Please do add a comment explaining this.

Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>

Regards, Joonas
Chris Wilson Sept. 19, 2016, 11:32 a.m. UTC | #5
On Mon, Sep 19, 2016 at 01:47:30PM +0300, Joonas Lahtinen wrote:
> On ke, 2016-09-14 at 07:52 +0100, Chris Wilson wrote:
> > @@ -2677,8 +2681,21 @@ static void intel_ring_default_vfuncs(struct drm_i915_private *dev_priv,
> >  	engine->reset_hw = reset_ring_common;
> >  
> >  	engine->emit_request = i9xx_emit_request;
> > -	if (i915.semaphores)
> > +	engine->emit_request_sz = i9xx_emit_request_sz;
> > +	if (i915.semaphores) {
> > +		int num_rings;
> 
> 'initialized_rings' to differentiate as suggested by Tvrtko too.

Tvrtko wasn't referring to this. The point is that we don't know
initialized_rings here, just the declared set of rings we think
the hardware is supposed to have.
-Chris
Joonas Lahtinen Sept. 19, 2016, 4:09 p.m. UTC | #6
On ma, 2016-09-19 at 12:32 +0100, Chris Wilson wrote:
> On Mon, Sep 19, 2016 at 01:47:30PM +0300, Joonas Lahtinen wrote:
> > On ke, 2016-09-14 at 07:52 +0100, Chris Wilson wrote:
> > > @@ -2677,8 +2681,21 @@ static void intel_ring_default_vfuncs(struct drm_i915_private *dev_priv,
> > >     engine->reset_hw = reset_ring_common;
> > >  
> > >     engine->emit_request = i9xx_emit_request;
> > > -   if (i915.semaphores)
> > > +   engine->emit_request_sz = i9xx_emit_request_sz;
> > > +   if (i915.semaphores) {
> > > +           int num_rings;
> > 
> > 'initialized_rings' to differentiate as suggested by Tvrtko too.
> 
> Tvrtko wasn't referring to this. The point is that we don't know
> initialized_rings here, just the declared set of rings we think
> the hardware is supposed to have.

Can't we afford to calculate this to the info struct anyway?

Regards, Joonas
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/i915_gem_request.c b/drivers/gpu/drm/i915/i915_gem_request.c
index ebc2feba3e50..9a735e2d5aea 100644
--- a/drivers/gpu/drm/i915/i915_gem_request.c
+++ b/drivers/gpu/drm/i915/i915_gem_request.c
@@ -425,6 +425,7 @@  i915_gem_request_alloc(struct intel_engine_cs *engine,
 	 * away, e.g. because a GPU scheduler has deferred it.
 	 */
 	req->reserved_space = MIN_SPACE_FOR_ADD_REQUEST;
+	GEM_BUG_ON(req->reserved_space < engine->emit_request_sz);
 
 	if (i915.enable_execlists)
 		ret = intel_logical_ring_alloc_request_extras(req);
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 00fcf36ba919..7e944a0acc10 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -1572,6 +1572,8 @@  static int gen8_emit_request(struct drm_i915_gem_request *request)
 	return intel_logical_ring_advance(request);
 }
 
+static const int gen8_emit_request_sz = 6 + WA_TAIL_DWORDS;
+
 static int gen8_emit_request_render(struct drm_i915_gem_request *request)
 {
 	struct intel_ring *ring = request->ring;
@@ -1603,6 +1605,8 @@  static int gen8_emit_request_render(struct drm_i915_gem_request *request)
 	return intel_logical_ring_advance(request);
 }
 
+static const int gen8_emit_request_render_sz = 8 + WA_TAIL_DWORDS;
+
 static int gen8_init_rcs_context(struct drm_i915_gem_request *req)
 {
 	int ret;
@@ -1677,6 +1681,7 @@  logical_ring_default_vfuncs(struct intel_engine_cs *engine)
 	engine->reset_hw = reset_common_ring;
 	engine->emit_flush = gen8_emit_flush;
 	engine->emit_request = gen8_emit_request;
+	engine->emit_request_sz = gen8_emit_request_sz;
 	engine->submit_request = execlists_submit_request;
 
 	engine->irq_enable = gen8_logical_ring_enable_irq;
@@ -1799,6 +1804,7 @@  int logical_render_ring_init(struct intel_engine_cs *engine)
 	engine->init_context = gen8_init_rcs_context;
 	engine->emit_flush = gen8_emit_flush_render;
 	engine->emit_request = gen8_emit_request_render;
+	engine->emit_request_sz = gen8_emit_request_render_sz;
 
 	ret = intel_engine_create_scratch(engine, 4096);
 	if (ret)
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 597e35c9b699..c8c9ad40fd93 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -1405,6 +1405,8 @@  static int i9xx_emit_request(struct drm_i915_gem_request *req)
 	return 0;
 }
 
+static const int i9xx_emit_request_sz = 4;
+
 /**
  * gen6_sema_emit_request - Update the semaphore mailbox registers
  *
@@ -1458,6 +1460,8 @@  static int gen8_render_emit_request(struct drm_i915_gem_request *req)
 	return 0;
 }
 
+static const int gen8_render_emit_request_sz = 8;
+
 /**
  * intel_ring_sync - sync the waiter to the signaller on seqno
  *
@@ -2677,8 +2681,21 @@  static void intel_ring_default_vfuncs(struct drm_i915_private *dev_priv,
 	engine->reset_hw = reset_ring_common;
 
 	engine->emit_request = i9xx_emit_request;
-	if (i915.semaphores)
+	engine->emit_request_sz = i9xx_emit_request_sz;
+	if (i915.semaphores) {
+		int num_rings;
+
 		engine->emit_request = gen6_sema_emit_request;
+
+		num_rings = hweight32(INTEL_INFO(dev_priv)->ring_mask) - 1;
+		if (INTEL_GEN(dev_priv) >= 8) {
+			engine->emit_request_sz += num_rings * 6;
+		} else {
+			engine->emit_request_sz += num_rings * 3;
+			if (num_rings & 1)
+				engine->emit_request_sz++;
+		}
+	}
 	engine->submit_request = i9xx_submit_request;
 
 	if (INTEL_GEN(dev_priv) >= 8)
@@ -2706,9 +2723,17 @@  int intel_init_render_ring_buffer(struct intel_engine_cs *engine)
 	if (INTEL_GEN(dev_priv) >= 8) {
 		engine->init_context = intel_rcs_ctx_init;
 		engine->emit_request = gen8_render_emit_request;
+		engine->emit_request_sz = gen8_render_emit_request_sz;
 		engine->emit_flush = gen8_render_ring_flush;
-		if (i915.semaphores)
+		if (i915.semaphores) {
+			int num_rings;
+
 			engine->semaphore.signal = gen8_rcs_signal;
+
+			num_rings =
+				hweight32(INTEL_INFO(dev_priv)->ring_mask) - 1;
+			engine->emit_request_sz += num_rings * 6;
+		}
 	} else if (INTEL_GEN(dev_priv) >= 6) {
 		engine->init_context = intel_rcs_ctx_init;
 		engine->emit_flush = gen7_render_ring_flush;
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index d6f80b3d66b4..47ad19f5441d 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -226,6 +226,7 @@  struct intel_engine_cs {
 #define I915_DISPATCH_PINNED BIT(1)
 #define I915_DISPATCH_RS     BIT(2)
 	int		(*emit_request)(struct drm_i915_gem_request *req);
+	int		emit_request_sz;
 
 	/* Pass the request to the hardware queue (e.g. directly into
 	 * the legacy ringbuffer or to the end of an execlist).