@@ -73,7 +73,8 @@ static void i915_context_del_id(struct drm_device *dev,
idr_remove(&dev_priv->i915_ctx_idr, ctx->ctx_id);
}
-int i915_context_validate(struct drm_device *dev, struct drm_file *file,
+struct drm_i915_gem_context *
+i915_context_validate(struct drm_device *dev, struct drm_file *file,
uint32_t ctx_id,
struct drm_i915_context_flag *ctx_flag, int count)
{
@@ -85,7 +86,7 @@ int i915_context_validate(struct drm_device *dev, struct drm_file *file,
ctx = i915_context_lookup_id(dev, ctx_id);
if (ctx == NULL) {
DRM_ERROR("Couldn't find context\n");
- return -ENXIO;
+ return ctx;
}
if ((!count || !ctx_flag))
@@ -117,7 +118,7 @@ int i915_context_validate(struct drm_device *dev, struct drm_file *file,
}
obj_priv = to_intel_bo(obj);
if (flag->offset && HAS_PPGTT(dev)) {
- /*
+ /*
* No need to check for overlaps because this is
* in their local GTT so they can only screw up
* themselves. But do check serious violations
@@ -163,13 +164,14 @@ out:
DRM_DEBUG_DRIVER("Context associated buffer has moved"
" %p->%p\n",
ppgtt_offset, obj_priv->gtt_offset);
- ret = -EIO;
- break;
+ mutex_unlock(&ctx->slot_mtx);
+ ctx = NULL;
+ return ctx;
}
}
mutex_unlock(&ctx->slot_mtx);
- return ret;
+ return ctx;
}
void i915_context_handle_binding(struct drm_i915_gem_object *obj)
@@ -1326,10 +1326,11 @@ extern void i915_context_init(struct drm_device *dev);
extern void i915_context_deinit(struct drm_device *dev);
extern void i915_context_close(struct drm_device *dev, struct drm_file *file);
struct drm_i915_context_flag;
-extern int i915_context_validate(struct drm_device *dev,
- struct drm_file *file, uint32_t ctx_id,
- struct drm_i915_context_flag *ctx_flag,
- int count);
+extern struct drm_i915_gem_context *
+i915_context_validate(struct drm_device *dev,
+ struct drm_file *file, uint32_t ctx_id,
+ struct drm_i915_context_flag *ctx_flag,
+ int count);
extern void i915_context_handle_binding(struct drm_i915_gem_object *obj);
#define LP_RING(d) (&((struct drm_i915_private *)(d))->ring[RCS])
@@ -990,6 +990,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
struct drm_i915_gem_object *batch_obj;
struct drm_clip_rect *cliprects = NULL;
struct intel_ring_buffer *ring;
+ struct drm_i915_gem_context *ctx;
u32 exec_start, exec_len;
u32 seqno;
u32 ctx_id;
@@ -1006,12 +1007,11 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
ctx_id = EXECBUFFER2_CTX_ID(args);
if (ctx_id) {
- ret = i915_context_validate(dev, file, ctx_id,
+ ctx = i915_context_validate(dev, file, ctx_id,
ctx_flags, flag_count);
- if (ret) {
- if (ret == -EIO)
- DRM_DEBUG_DRIVER("Context resubmission required\n");
- return ret;
+ if (!ctx) {
+ DRM_DEBUG_DRIVER("Context resubmission required\n");
+ return -EIO;
}
}
#if WATCH_EXEC
@@ -1203,6 +1203,9 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
}
}
+ if (!dev_priv->ctx_disable)
+ ring->context_switch(ring, ctx, I915_CONTEXT_NORMAL_SWITCH);
+
exec_start = batch_obj->gtt_offset + args->batch_start_offset;
exec_len = args->batch_len;
if (cliprects) {
@@ -82,7 +82,7 @@ struct intel_ring_buffer {
struct drm_i915_gem_context *last_context;
void (*context_switch)(struct intel_ring_buffer *ring,
struct drm_i915_gem_context *ctx,
- uint32_t flags);
+ u32 flags);
/**
* List of objects currently involved in rendering from the