diff options
| author | Mika Kuoppala <mika.kuoppala@linux.intel.com> | 2013-11-26 09:14:33 -0500 |
|---|---|---|
| committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2013-12-04 07:20:31 -0500 |
| commit | d299cce76e001406df40c4ff712b33fccbce1222 (patch) | |
| tree | d54530b66eaf7f365f6418ad7d1aa82c27710db0 | |
| parent | 70903c3ba8fa5ad391d1519c60666a389e4be597 (diff) | |
drm/i915: check context reset stats before relocations
Doing it early prevents moving and relocating objects in vain
for contexts that won't get any GPU time.
Reported-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Mika Kuoppala <mika.kuoppala@intel.com>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
| -rw-r--r-- | drivers/gpu/drm/i915/i915_gem_execbuffer.c | 38 |
1 files changed, 25 insertions, 13 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index b800fe449530..9282b4c411f6 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c | |||
| @@ -884,6 +884,24 @@ validate_exec_list(struct drm_i915_gem_exec_object2 *exec, | |||
| 884 | return 0; | 884 | return 0; |
| 885 | } | 885 | } |
| 886 | 886 | ||
| 887 | static int | ||
| 888 | i915_gem_validate_context(struct drm_device *dev, struct drm_file *file, | ||
| 889 | const u32 ctx_id) | ||
| 890 | { | ||
| 891 | struct i915_ctx_hang_stats *hs; | ||
| 892 | |||
| 893 | hs = i915_gem_context_get_hang_stats(dev, file, ctx_id); | ||
| 894 | if (IS_ERR(hs)) | ||
| 895 | return PTR_ERR(hs); | ||
| 896 | |||
| 897 | if (hs->banned) { | ||
| 898 | DRM_DEBUG("Context %u tried to submit while banned\n", ctx_id); | ||
| 899 | return -EIO; | ||
| 900 | } | ||
| 901 | |||
| 902 | return 0; | ||
| 903 | } | ||
| 904 | |||
| 887 | static void | 905 | static void |
| 888 | i915_gem_execbuffer_move_to_active(struct list_head *vmas, | 906 | i915_gem_execbuffer_move_to_active(struct list_head *vmas, |
| 889 | struct intel_ring_buffer *ring) | 907 | struct intel_ring_buffer *ring) |
| @@ -963,8 +981,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
| 963 | struct drm_i915_gem_object *batch_obj; | 981 | struct drm_i915_gem_object *batch_obj; |
| 964 | struct drm_clip_rect *cliprects = NULL; | 982 | struct drm_clip_rect *cliprects = NULL; |
| 965 | struct intel_ring_buffer *ring; | 983 | struct intel_ring_buffer *ring; |
| 966 | struct i915_ctx_hang_stats *hs; | 984 | const u32 ctx_id = i915_execbuffer2_get_context_id(*args); |
| 967 | u32 ctx_id = i915_execbuffer2_get_context_id(*args); | ||
| 968 | u32 exec_start, exec_len; | 985 | u32 exec_start, exec_len; |
| 969 | u32 mask, flags; | 986 | u32 mask, flags; |
| 970 | int ret, mode, i; | 987 | int ret, mode, i; |
| @@ -1101,6 +1118,12 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
| 1101 | goto pre_mutex_err; | 1118 | goto pre_mutex_err; |
| 1102 | } | 1119 | } |
| 1103 | 1120 | ||
| 1121 | ret = i915_gem_validate_context(dev, file, ctx_id); | ||
| 1122 | if (ret) { | ||
| 1123 | mutex_unlock(&dev->struct_mutex); | ||
| 1124 | goto pre_mutex_err; | ||
| 1125 | } | ||
| 1126 | |||
| 1104 | eb = eb_create(args); | 1127 | eb = eb_create(args); |
| 1105 | if (eb == NULL) { | 1128 | if (eb == NULL) { |
| 1106 | mutex_unlock(&dev->struct_mutex); | 1129 | mutex_unlock(&dev->struct_mutex); |
| @@ -1153,17 +1176,6 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
| 1153 | if (ret) | 1176 | if (ret) |
| 1154 | goto err; | 1177 | goto err; |
| 1155 | 1178 | ||
| 1156 | hs = i915_gem_context_get_hang_stats(dev, file, ctx_id); | ||
| 1157 | if (IS_ERR(hs)) { | ||
| 1158 | ret = PTR_ERR(hs); | ||
| 1159 | goto err; | ||
| 1160 | } | ||
| 1161 | |||
| 1162 | if (hs->banned) { | ||
| 1163 | ret = -EIO; | ||
| 1164 | goto err; | ||
| 1165 | } | ||
| 1166 | |||
| 1167 | ret = i915_switch_context(ring, file, ctx_id); | 1179 | ret = i915_switch_context(ring, file, ctx_id); |
| 1168 | if (ret) | 1180 | if (ret) |
| 1169 | goto err; | 1181 | goto err; |
