@@ -97,7 +97,7 @@
static struct i915_hw_context *
i915_gem_context_get(struct drm_i915_file_private *file_priv, u32 id);
-static int do_switch(struct i915_hw_context *to);
+static int do_switch(struct i915_hw_context *to, bool force);
static int get_context_size(struct drm_device *dev)
{
@@ -225,7 +225,7 @@ static int create_default_context(struct drm_i915_private *dev_priv)
if (ret)
goto err_destroy;
- ret = do_switch(ctx);
+ ret = do_switch(ctx, false);
if (ret)
goto err_unpin;
@@ -256,7 +256,7 @@ void i915_gem_context_init(struct drm_device *dev)
* context so our HW CCID matches what we think it should be in software.
*/
if (dev_priv->ring[RCS].default_context) {
- int ret = do_switch(dev_priv->ring[RCS].default_context);
+ int ret = do_switch(dev_priv->ring[RCS].default_context, false);
if (ret) {
DRM_ERROR("HW contexts were broken after resume\n");
i915_gem_context_fini(dev);
@@ -373,7 +373,7 @@ mi_set_context(struct intel_ring_buffer *ring,
return ret;
}
-static int do_switch(struct i915_hw_context *to)
+static int do_switch(struct i915_hw_context *to, bool force)
{
struct intel_ring_buffer *ring = to->ring;
struct drm_i915_gem_object *from_obj = ring->last_context_obj;
@@ -382,7 +382,7 @@ static int do_switch(struct i915_hw_context *to)
BUG_ON(from_obj != NULL && from_obj->pin_count == 0);
- if (from_obj == to->obj)
+ if (!force && (from_obj == to->obj))
return 0;
ret = i915_gem_object_pin(to->obj, CONTEXT_ALIGN, false);
@@ -403,10 +403,10 @@ static int do_switch(struct i915_hw_context *to)
if (!to->obj->has_global_gtt_mapping)
i915_gem_gtt_bind_object(to->obj, to->obj->cache_level);
- if (!to->is_initialized || is_default_context(to))
- hw_flags |= MI_RESTORE_INHIBIT;
- else if (WARN_ON_ONCE(from_obj == to->obj)) /* not yet expected */
+ if (force) {
hw_flags |= MI_FORCE_RESTORE;
+ } else if (!to->is_initialized || is_default_context(to))
+ hw_flags |= MI_RESTORE_INHIBIT;
ret = mi_set_context(ring, to, hw_flags);
if (ret) {
@@ -482,7 +482,7 @@ int i915_switch_context(struct intel_ring_buffer *ring,
return -ENOENT;
}
- return do_switch(to);
+ return do_switch(to, false);
}
int i915_gem_context_create_ioctl(struct drm_device *dev, void *data,