* 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_breadcrumb_sz);
 
        if (i915.enable_execlists)
                ret = intel_logical_ring_alloc_request_extras(req);
 
        return intel_logical_ring_advance(request);
 }
 
+static const int gen8_emit_breadcrumb_sz = 6 + WA_TAIL_DWORDS;
+
 static int gen8_emit_breadcrumb_render(struct drm_i915_gem_request *request)
 {
        struct intel_ring *ring = request->ring;
        return intel_logical_ring_advance(request);
 }
 
+static const int gen8_emit_breadcrumb_render_sz = 8 + WA_TAIL_DWORDS;
+
 static int gen8_init_rcs_context(struct drm_i915_gem_request *req)
 {
        int ret;
        engine->reset_hw = reset_common_ring;
        engine->emit_flush = gen8_emit_flush;
        engine->emit_breadcrumb = gen8_emit_breadcrumb;
+       engine->emit_breadcrumb_sz = gen8_emit_breadcrumb_sz;
        engine->submit_request = execlists_submit_request;
 
        engine->irq_enable = gen8_logical_ring_enable_irq;
        engine->init_context = gen8_init_rcs_context;
        engine->emit_flush = gen8_emit_flush_render;
        engine->emit_breadcrumb = gen8_emit_breadcrumb_render;
+       engine->emit_breadcrumb_sz = gen8_emit_breadcrumb_render_sz;
 
        ret = intel_engine_create_scratch(engine, 4096);
        if (ret)
 
        return 0;
 }
 
+static const int i9xx_emit_breadcrumb_sz = 4;
+
 /**
  * gen6_sema_emit_breadcrumb - Update the semaphore mailbox registers
  *
        return 0;
 }
 
+static const int gen8_render_emit_breadcrumb_sz = 8;
+
 /**
  * intel_ring_sync - sync the waiter to the signaller on seqno
  *
        engine->reset_hw = reset_ring_common;
 
        engine->emit_breadcrumb = i9xx_emit_breadcrumb;
-       if (i915.semaphores)
+       engine->emit_breadcrumb_sz = i9xx_emit_breadcrumb_sz;
+       if (i915.semaphores) {
+               int num_rings;
+
                engine->emit_breadcrumb = gen6_sema_emit_breadcrumb;
+
+               num_rings = hweight32(INTEL_INFO(dev_priv)->ring_mask) - 1;
+               if (INTEL_GEN(dev_priv) >= 8) {
+                       engine->emit_breadcrumb_sz += num_rings * 6;
+               } else {
+                       engine->emit_breadcrumb_sz += num_rings * 3;
+                       if (num_rings & 1)
+                               engine->emit_breadcrumb_sz++;
+               }
+       }
        engine->submit_request = i9xx_submit_request;
 
        if (INTEL_GEN(dev_priv) >= 8)
        if (INTEL_GEN(dev_priv) >= 8) {
                engine->init_context = intel_rcs_ctx_init;
                engine->emit_breadcrumb = gen8_render_emit_breadcrumb;
+               engine->emit_breadcrumb_sz = gen8_render_emit_breadcrumb_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_breadcrumb_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;
 
 #define I915_DISPATCH_PINNED BIT(1)
 #define I915_DISPATCH_RS     BIT(2)
        int             (*emit_breadcrumb)(struct drm_i915_gem_request *req);
+       int             emit_breadcrumb_sz;
 
        /* Pass the request to the hardware queue (e.g. directly into
         * the legacy ringbuffer or to the end of an execlist).