diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 20cd6d8..778b14a 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -884,6 +884,7 @@ struct intel_context {
 	struct {
 		struct drm_i915_gem_object *state;
 		struct intel_ringbuffer *ringbuf;
+		bool unsaved;
 		int pin_count;
 	} engine[I915_NUM_RINGS];
 
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index f1e3fde..273946d 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1385,6 +1385,13 @@ __i915_gem_request_retire__upto(struct drm_i915_gem_request *req)
 		tmp = list_first_entry(&engine->request_list,
 				       typeof(*tmp), list);
 
+		if (i915.enable_execlists) {
+			unsigned long flags;
+
+			spin_lock_irqsave(&engine->execlist_lock, flags);
+			intel_lr_context_complete_check(tmp);
+			spin_unlock_irqrestore(&engine->execlist_lock, flags);
+		}
 		i915_gem_request_retire(tmp);
 	} while (tmp != req);
 
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 06180dc..d82e903 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -566,13 +566,17 @@ static int execlists_context_queue(struct drm_i915_gem_request *request)
 	struct drm_i915_gem_request *cursor;
 	int num_elements = 0;
 
-	if (request->ctx != ring->default_context)
-		intel_lr_context_pin(request);
-
 	i915_gem_request_reference(request);
 
 	spin_lock_irq(&ring->execlist_lock);
 
+	if (request->ctx != ring->default_context) {
+		if (!request->ctx->engine[ring->id].unsaved) {
+			intel_lr_context_pin(request);
+			request->ctx->engine[ring->id].unsaved = true;
+		}
+	}
+
 	list_for_each_entry(cursor, &ring->execlist_queue, execlist_link)
 		if (++num_elements > 2)
 			break;
@@ -958,12 +962,6 @@ void intel_execlists_retire_requests(struct intel_engine_cs *ring)
 	spin_unlock_irq(&ring->execlist_lock);
 
 	list_for_each_entry_safe(req, tmp, &retired_list, execlist_link) {
-		struct intel_context *ctx = req->ctx;
-		struct drm_i915_gem_object *ctx_obj =
-				ctx->engine[ring->id].state;
-
-		if (ctx_obj && (ctx != ring->default_context))
-			intel_lr_context_unpin(req);
 		list_del(&req->execlist_link);
 		i915_gem_request_unreference(req);
 	}
@@ -1073,6 +1071,31 @@ void intel_lr_context_unpin(struct drm_i915_gem_request *rq)
 	}
 }
 
+void intel_lr_context_complete_check(struct drm_i915_gem_request *req)
+{
+	struct intel_engine_cs *ring = req->ring;
+
+	assert_spin_locked(&ring->execlist_lock);
+
+	if (ring->last_context && ring->last_context != req->ctx) {
+		if (req->ctx != ring->default_context
+			&& ring->last_context->engine[ring->id].unsaved) {
+			/* Create fake request for unpinning the old context */
+			struct drm_i915_gem_request tmp;
+
+			tmp.ring = ring;
+			tmp.ctx = ring->last_context;
+			tmp.ringbuf =
+				ring->last_context->engine[ring->id].ringbuf;
+
+			intel_lr_context_unpin(&tmp);
+			ring->last_context->engine[ring->id].unsaved = false;
+			ring->last_context = NULL;
+		}
+	}
+	ring->last_context = req->ctx;
+}
+
 static int intel_logical_ring_workarounds_emit(struct drm_i915_gem_request *req)
 {
 	int ret, i;
@@ -2390,7 +2413,22 @@ void intel_lr_context_free(struct intel_context *ctx)
 				intel_unpin_ringbuffer_obj(ringbuf);
 				i915_gem_object_ggtt_unpin(ctx_obj);
 			}
-			WARN_ON(ctx->engine[ring->id].pin_count);
+
+			if (ctx->engine[ring->id].unsaved) {
+				/**
+				 * Create fake request for unpinning the old
+				 * context
+				 */
+				struct drm_i915_gem_request tmp;
+
+				tmp.ring = ring;
+				tmp.ctx = ctx;
+				tmp.ringbuf = ringbuf;
+				intel_lr_context_unpin(&tmp);
+				ctx->engine[ring->id].unsaved = false;
+			}
+
+			WARN_ON(ctx->engine[i].pin_count);
 			intel_ringbuffer_free(ringbuf);
 			drm_gem_object_unreference(&ctx_obj->base);
 		}
diff --git a/drivers/gpu/drm/i915/intel_lrc.h b/drivers/gpu/drm/i915/intel_lrc.h
index 4e60d54..cbc42b8 100644
--- a/drivers/gpu/drm/i915/intel_lrc.h
+++ b/drivers/gpu/drm/i915/intel_lrc.h
@@ -86,6 +86,7 @@ void intel_lr_context_reset(struct drm_device *dev,
 			struct intel_context *ctx);
 uint64_t intel_lr_context_descriptor(struct intel_context *ctx,
 				     struct intel_engine_cs *ring);
+void intel_lr_context_complete_check(struct drm_i915_gem_request *req);
 
 /* Execlists */
 int intel_sanitize_enable_execlists(struct drm_device *dev, int enable_execlists);
