diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2010-10-27 11:11:02 -0400 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2010-10-27 18:31:03 -0400 |
commit | 3cce469cab880ef8990d2d16d745bf85443fc998 (patch) | |
tree | 929b8ae6f2a693d2a793e8ddd82d5c0957b2414d | |
parent | b2223497b44a4701d1be873d1e9453d7f720043b (diff) |
drm/i915: Propagate error from failing to queue a request
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 36 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_overlay.c | 20 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_ringbuffer.c | 128 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_ringbuffer.h | 4 |
5 files changed, 111 insertions, 85 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 2af8e1604b44..f168e82c10aa 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -1041,10 +1041,10 @@ int i915_gem_do_init(struct drm_device *dev, unsigned long start, | |||
1041 | unsigned long end); | 1041 | unsigned long end); |
1042 | int i915_gpu_idle(struct drm_device *dev); | 1042 | int i915_gpu_idle(struct drm_device *dev); |
1043 | int i915_gem_idle(struct drm_device *dev); | 1043 | int i915_gem_idle(struct drm_device *dev); |
1044 | uint32_t i915_add_request(struct drm_device *dev, | 1044 | int i915_add_request(struct drm_device *dev, |
1045 | struct drm_file *file_priv, | 1045 | struct drm_file *file_priv, |
1046 | struct drm_i915_gem_request *request, | 1046 | struct drm_i915_gem_request *request, |
1047 | struct intel_ring_buffer *ring); | 1047 | struct intel_ring_buffer *ring); |
1048 | int i915_do_wait_request(struct drm_device *dev, | 1048 | int i915_do_wait_request(struct drm_device *dev, |
1049 | uint32_t seqno, | 1049 | uint32_t seqno, |
1050 | bool interruptible, | 1050 | bool interruptible, |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 74f5525d156f..d0aaf97ac6e0 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -1683,7 +1683,7 @@ i915_gem_process_flushing_list(struct drm_device *dev, | |||
1683 | } | 1683 | } |
1684 | } | 1684 | } |
1685 | 1685 | ||
1686 | uint32_t | 1686 | int |
1687 | i915_add_request(struct drm_device *dev, | 1687 | i915_add_request(struct drm_device *dev, |
1688 | struct drm_file *file, | 1688 | struct drm_file *file, |
1689 | struct drm_i915_gem_request *request, | 1689 | struct drm_i915_gem_request *request, |
@@ -1693,17 +1693,17 @@ i915_add_request(struct drm_device *dev, | |||
1693 | struct drm_i915_file_private *file_priv = NULL; | 1693 | struct drm_i915_file_private *file_priv = NULL; |
1694 | uint32_t seqno; | 1694 | uint32_t seqno; |
1695 | int was_empty; | 1695 | int was_empty; |
1696 | int ret; | ||
1697 | |||
1698 | BUG_ON(request == NULL); | ||
1696 | 1699 | ||
1697 | if (file != NULL) | 1700 | if (file != NULL) |
1698 | file_priv = file->driver_priv; | 1701 | file_priv = file->driver_priv; |
1699 | 1702 | ||
1700 | if (request == NULL) { | 1703 | ret = ring->add_request(ring, &seqno); |
1701 | request = kzalloc(sizeof(*request), GFP_KERNEL); | 1704 | if (ret) |
1702 | if (request == NULL) | 1705 | return ret; |
1703 | return 0; | ||
1704 | } | ||
1705 | 1706 | ||
1706 | seqno = ring->add_request(ring, 0); | ||
1707 | ring->outstanding_lazy_request = false; | 1707 | ring->outstanding_lazy_request = false; |
1708 | 1708 | ||
1709 | request->seqno = seqno; | 1709 | request->seqno = seqno; |
@@ -1727,7 +1727,7 @@ i915_add_request(struct drm_device *dev, | |||
1727 | queue_delayed_work(dev_priv->wq, | 1727 | queue_delayed_work(dev_priv->wq, |
1728 | &dev_priv->mm.retire_work, HZ); | 1728 | &dev_priv->mm.retire_work, HZ); |
1729 | } | 1729 | } |
1730 | return seqno; | 1730 | return 0; |
1731 | } | 1731 | } |
1732 | 1732 | ||
1733 | /** | 1733 | /** |
@@ -1964,9 +1964,19 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno, | |||
1964 | return -EAGAIN; | 1964 | return -EAGAIN; |
1965 | 1965 | ||
1966 | if (ring->outstanding_lazy_request) { | 1966 | if (ring->outstanding_lazy_request) { |
1967 | seqno = i915_add_request(dev, NULL, NULL, ring); | 1967 | struct drm_i915_gem_request *request; |
1968 | if (seqno == 0) | 1968 | |
1969 | request = kzalloc(sizeof(*request), GFP_KERNEL); | ||
1970 | if (request == NULL) | ||
1969 | return -ENOMEM; | 1971 | return -ENOMEM; |
1972 | |||
1973 | ret = i915_add_request(dev, NULL, request, ring); | ||
1974 | if (ret) { | ||
1975 | kfree(request); | ||
1976 | return ret; | ||
1977 | } | ||
1978 | |||
1979 | seqno = request->seqno; | ||
1970 | } | 1980 | } |
1971 | BUG_ON(seqno == dev_priv->next_seqno); | 1981 | BUG_ON(seqno == dev_priv->next_seqno); |
1972 | 1982 | ||
@@ -3844,8 +3854,10 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
3844 | */ | 3854 | */ |
3845 | i915_retire_commands(dev, ring); | 3855 | i915_retire_commands(dev, ring); |
3846 | 3856 | ||
3847 | i915_add_request(dev, file, request, ring); | 3857 | if (i915_add_request(dev, file, request, ring)) |
3848 | request = NULL; | 3858 | ring->outstanding_lazy_request = true; |
3859 | else | ||
3860 | request = NULL; | ||
3849 | 3861 | ||
3850 | err: | 3862 | err: |
3851 | for (i = 0; i < args->buffer_count; i++) { | 3863 | for (i = 0; i < args->buffer_count; i++) { |
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index 78fa6a249964..2d4a6968cd76 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c | |||
@@ -221,11 +221,12 @@ static int intel_overlay_do_wait_request(struct intel_overlay *overlay, | |||
221 | int ret; | 221 | int ret; |
222 | 222 | ||
223 | BUG_ON(overlay->last_flip_req); | 223 | BUG_ON(overlay->last_flip_req); |
224 | overlay->last_flip_req = | 224 | ret = i915_add_request(dev, NULL, request, &dev_priv->render_ring); |
225 | i915_add_request(dev, NULL, request, &dev_priv->render_ring); | 225 | if (ret) { |
226 | if (overlay->last_flip_req == 0) | 226 | kfree(request); |
227 | return -ENOMEM; | 227 | return ret; |
228 | 228 | } | |
229 | overlay->last_flip_req = request->seqno; | ||
229 | overlay->flip_tail = tail; | 230 | overlay->flip_tail = tail; |
230 | ret = i915_do_wait_request(dev, | 231 | ret = i915_do_wait_request(dev, |
231 | overlay->last_flip_req, true, | 232 | overlay->last_flip_req, true, |
@@ -363,8 +364,13 @@ static int intel_overlay_continue(struct intel_overlay *overlay, | |||
363 | OUT_RING(flip_addr); | 364 | OUT_RING(flip_addr); |
364 | ADVANCE_LP_RING(); | 365 | ADVANCE_LP_RING(); |
365 | 366 | ||
366 | overlay->last_flip_req = | 367 | ret = i915_add_request(dev, NULL, request, &dev_priv->render_ring); |
367 | i915_add_request(dev, NULL, request, &dev_priv->render_ring); | 368 | if (ret) { |
369 | kfree(request); | ||
370 | return ret; | ||
371 | } | ||
372 | |||
373 | overlay->last_flip_req = request->seqno; | ||
368 | return 0; | 374 | return 0; |
369 | } | 375 | } |
370 | 376 | ||
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 6fe42c1f4ea9..4803b32f308f 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
@@ -234,28 +234,28 @@ do { \ | |||
234 | * | 234 | * |
235 | * Returned sequence numbers are nonzero on success. | 235 | * Returned sequence numbers are nonzero on success. |
236 | */ | 236 | */ |
237 | static u32 | 237 | static int |
238 | render_ring_add_request(struct intel_ring_buffer *ring, | 238 | render_ring_add_request(struct intel_ring_buffer *ring, |
239 | u32 flush_domains) | 239 | u32 *result) |
240 | { | 240 | { |
241 | struct drm_device *dev = ring->dev; | 241 | struct drm_device *dev = ring->dev; |
242 | drm_i915_private_t *dev_priv = dev->dev_private; | 242 | drm_i915_private_t *dev_priv = dev->dev_private; |
243 | u32 seqno; | 243 | u32 seqno = i915_gem_get_seqno(dev); |
244 | 244 | int ret; | |
245 | seqno = i915_gem_get_seqno(dev); | ||
246 | 245 | ||
247 | if (IS_GEN6(dev)) { | 246 | if (IS_GEN6(dev)) { |
248 | if (intel_ring_begin(ring, 6) == 0) { | 247 | ret = intel_ring_begin(ring, 6); |
249 | intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | 3); | 248 | if (ret) |
250 | intel_ring_emit(ring, PIPE_CONTROL_QW_WRITE | | 249 | return ret; |
251 | PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_IS_FLUSH | | 250 | |
252 | PIPE_CONTROL_NOTIFY); | 251 | intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | 3); |
253 | intel_ring_emit(ring, dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT); | 252 | intel_ring_emit(ring, PIPE_CONTROL_QW_WRITE | |
254 | intel_ring_emit(ring, seqno); | 253 | PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_IS_FLUSH | |
255 | intel_ring_emit(ring, 0); | 254 | PIPE_CONTROL_NOTIFY); |
256 | intel_ring_emit(ring, 0); | 255 | intel_ring_emit(ring, dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT); |
257 | intel_ring_advance(ring); | 256 | intel_ring_emit(ring, seqno); |
258 | } | 257 | intel_ring_emit(ring, 0); |
258 | intel_ring_emit(ring, 0); | ||
259 | } else if (HAS_PIPE_CONTROL(dev)) { | 259 | } else if (HAS_PIPE_CONTROL(dev)) { |
260 | u32 scratch_addr = dev_priv->seqno_gfx_addr + 128; | 260 | u32 scratch_addr = dev_priv->seqno_gfx_addr + 128; |
261 | 261 | ||
@@ -264,42 +264,47 @@ render_ring_add_request(struct intel_ring_buffer *ring, | |||
264 | * PIPE_NOTIFY buffers out to memory before requesting | 264 | * PIPE_NOTIFY buffers out to memory before requesting |
265 | * an interrupt. | 265 | * an interrupt. |
266 | */ | 266 | */ |
267 | if (intel_ring_begin(ring, 32) == 0) { | 267 | ret = intel_ring_begin(ring, 32); |
268 | intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | | 268 | if (ret) |
269 | PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH); | 269 | return ret; |
270 | intel_ring_emit(ring, dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT); | 270 | |
271 | intel_ring_emit(ring, seqno); | 271 | intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | |
272 | intel_ring_emit(ring, 0); | 272 | PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH); |
273 | PIPE_CONTROL_FLUSH(ring, scratch_addr); | 273 | intel_ring_emit(ring, dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT); |
274 | scratch_addr += 128; /* write to separate cachelines */ | 274 | intel_ring_emit(ring, seqno); |
275 | PIPE_CONTROL_FLUSH(ring, scratch_addr); | 275 | intel_ring_emit(ring, 0); |
276 | scratch_addr += 128; | 276 | PIPE_CONTROL_FLUSH(ring, scratch_addr); |
277 | PIPE_CONTROL_FLUSH(ring, scratch_addr); | 277 | scratch_addr += 128; /* write to separate cachelines */ |
278 | scratch_addr += 128; | 278 | PIPE_CONTROL_FLUSH(ring, scratch_addr); |
279 | PIPE_CONTROL_FLUSH(ring, scratch_addr); | 279 | scratch_addr += 128; |
280 | scratch_addr += 128; | 280 | PIPE_CONTROL_FLUSH(ring, scratch_addr); |
281 | PIPE_CONTROL_FLUSH(ring, scratch_addr); | 281 | scratch_addr += 128; |
282 | scratch_addr += 128; | 282 | PIPE_CONTROL_FLUSH(ring, scratch_addr); |
283 | PIPE_CONTROL_FLUSH(ring, scratch_addr); | 283 | scratch_addr += 128; |
284 | intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | | 284 | PIPE_CONTROL_FLUSH(ring, scratch_addr); |
285 | PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH | | 285 | scratch_addr += 128; |
286 | PIPE_CONTROL_NOTIFY); | 286 | PIPE_CONTROL_FLUSH(ring, scratch_addr); |
287 | intel_ring_emit(ring, dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT); | 287 | intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | |
288 | intel_ring_emit(ring, seqno); | 288 | PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH | |
289 | intel_ring_emit(ring, 0); | 289 | PIPE_CONTROL_NOTIFY); |
290 | intel_ring_advance(ring); | 290 | intel_ring_emit(ring, dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT); |
291 | } | 291 | intel_ring_emit(ring, seqno); |
292 | intel_ring_emit(ring, 0); | ||
292 | } else { | 293 | } else { |
293 | if (intel_ring_begin(ring, 4) == 0) { | 294 | ret = intel_ring_begin(ring, 4); |
294 | intel_ring_emit(ring, MI_STORE_DWORD_INDEX); | 295 | if (ret) |
295 | intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); | 296 | return ret; |
296 | intel_ring_emit(ring, seqno); | ||
297 | 297 | ||
298 | intel_ring_emit(ring, MI_USER_INTERRUPT); | 298 | intel_ring_emit(ring, MI_STORE_DWORD_INDEX); |
299 | intel_ring_advance(ring); | 299 | intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); |
300 | } | 300 | intel_ring_emit(ring, seqno); |
301 | |||
302 | intel_ring_emit(ring, MI_USER_INTERRUPT); | ||
301 | } | 303 | } |
302 | return seqno; | 304 | |
305 | intel_ring_advance(ring); | ||
306 | *result = seqno; | ||
307 | return 0; | ||
303 | } | 308 | } |
304 | 309 | ||
305 | static u32 | 310 | static u32 |
@@ -370,25 +375,28 @@ bsd_ring_flush(struct intel_ring_buffer *ring, | |||
370 | } | 375 | } |
371 | } | 376 | } |
372 | 377 | ||
373 | static u32 | 378 | static int |
374 | ring_add_request(struct intel_ring_buffer *ring, | 379 | ring_add_request(struct intel_ring_buffer *ring, |
375 | u32 flush_domains) | 380 | u32 *result) |
376 | { | 381 | { |
377 | u32 seqno; | 382 | u32 seqno; |
383 | int ret; | ||
384 | |||
385 | ret = intel_ring_begin(ring, 4); | ||
386 | if (ret) | ||
387 | return ret; | ||
378 | 388 | ||
379 | seqno = i915_gem_get_seqno(ring->dev); | 389 | seqno = i915_gem_get_seqno(ring->dev); |
380 | 390 | ||
381 | if (intel_ring_begin(ring, 4) == 0) { | 391 | intel_ring_emit(ring, MI_STORE_DWORD_INDEX); |
382 | intel_ring_emit(ring, MI_STORE_DWORD_INDEX); | 392 | intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); |
383 | intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); | 393 | intel_ring_emit(ring, seqno); |
384 | intel_ring_emit(ring, seqno); | 394 | intel_ring_emit(ring, MI_USER_INTERRUPT); |
385 | intel_ring_emit(ring, MI_USER_INTERRUPT); | 395 | intel_ring_advance(ring); |
386 | intel_ring_advance(ring); | ||
387 | } | ||
388 | 396 | ||
389 | DRM_DEBUG_DRIVER("%s %d\n", ring->name, seqno); | 397 | DRM_DEBUG_DRIVER("%s %d\n", ring->name, seqno); |
390 | 398 | *result = seqno; | |
391 | return seqno; | 399 | return 0; |
392 | } | 400 | } |
393 | 401 | ||
394 | static void | 402 | static void |
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 7ad9e94220b4..acd23374fe89 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h | |||
@@ -48,8 +48,8 @@ struct intel_ring_buffer { | |||
48 | void (*flush)(struct intel_ring_buffer *ring, | 48 | void (*flush)(struct intel_ring_buffer *ring, |
49 | u32 invalidate_domains, | 49 | u32 invalidate_domains, |
50 | u32 flush_domains); | 50 | u32 flush_domains); |
51 | u32 (*add_request)(struct intel_ring_buffer *ring, | 51 | int (*add_request)(struct intel_ring_buffer *ring, |
52 | u32 flush_domains); | 52 | u32 *seqno); |
53 | u32 (*get_seqno)(struct intel_ring_buffer *ring); | 53 | u32 (*get_seqno)(struct intel_ring_buffer *ring); |
54 | int (*dispatch_execbuffer)(struct intel_ring_buffer *ring, | 54 | int (*dispatch_execbuffer)(struct intel_ring_buffer *ring, |
55 | struct drm_i915_gem_execbuffer2 *exec, | 55 | struct drm_i915_gem_execbuffer2 *exec, |