aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2010-10-27 11:11:02 -0400
committerChris Wilson <chris@chris-wilson.co.uk>2010-10-27 18:31:03 -0400
commit3cce469cab880ef8990d2d16d745bf85443fc998 (patch)
tree929b8ae6f2a693d2a793e8ddd82d5c0957b2414d
parentb2223497b44a4701d1be873d1e9453d7f720043b (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.h8
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c36
-rw-r--r--drivers/gpu/drm/i915/intel_overlay.c20
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.c128
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.h4
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);
1042int i915_gpu_idle(struct drm_device *dev); 1042int i915_gpu_idle(struct drm_device *dev);
1043int i915_gem_idle(struct drm_device *dev); 1043int i915_gem_idle(struct drm_device *dev);
1044uint32_t i915_add_request(struct drm_device *dev, 1044int 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);
1048int i915_do_wait_request(struct drm_device *dev, 1048int 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
1686uint32_t 1686int
1687i915_add_request(struct drm_device *dev, 1687i915_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
3850err: 3862err:
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 */
237static u32 237static int
238render_ring_add_request(struct intel_ring_buffer *ring, 238render_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
305static u32 310static u32
@@ -370,25 +375,28 @@ bsd_ring_flush(struct intel_ring_buffer *ring,
370 } 375 }
371} 376}
372 377
373static u32 378static int
374ring_add_request(struct intel_ring_buffer *ring, 379ring_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
394static void 402static 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,