aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2012-11-27 11:22:52 -0500
committerDaniel Vetter <daniel.vetter@ffwll.ch>2012-11-29 05:43:52 -0500
commit9d7730914f4cd496e356acfab95b41075aa8eae8 (patch)
tree509e4ad7d5b7f32e3118fca228ce2f034403d634 /drivers/gpu/drm/i915
parent45e2b5f640b3766da3eda48f6c35f088155c06f3 (diff)
drm/i915: Preallocate next seqno before touching the ring
Based on the work by Mika Kuoppala, we realised that we need to handle seqno wraparound prior to committing our changes to the ring. The most obvious point then is to grab the seqno inside intel_ring_begin(), and then to reuse that seqno for all ring operations until the next request. As intel_ring_begin() can fail, the callers must already be prepared to handle such failure and so we can safely add further checks. This patch looks like it should be split up into the interface changes and the tweaks to move seqno wrapping from the execbuffer into the core seqno increment. However, I found no easy way to break it into incremental steps without introducing further broken behaviour. v2: Mika found a silly mistake and a subtle error in the existing code; inside i915_gem_retire_requests() we were resetting the sync_seqno of the target ring based on the seqno from this ring - which are only related by the order of their allocation, not retirement. Hence we were applying the optimisation that the rings were synchronised too early, fortunately the only real casualty there is the handling of seqno wrapping. v3: Do not forget to reset the sync_seqno upon module reinitialisation, ala resume. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Mika Kuoppala <mika.kuoppala@intel.com> Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=863861 Reviewed-by: Mika Kuoppala <mika.kuoppala@intel.com> [v2] Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915')
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h5
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c74
-rw-r--r--drivers/gpu/drm/i915/i915_gem_context.c3
-rw-r--r--drivers/gpu/drm/i915/i915_gem_execbuffer.c30
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.c49
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.h10
6 files changed, 89 insertions, 82 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 47c62f5125a7..45491c1ac7de 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1417,8 +1417,7 @@ int __must_check i915_mutex_lock_interruptible(struct drm_device *dev);
1417int i915_gem_object_sync(struct drm_i915_gem_object *obj, 1417int i915_gem_object_sync(struct drm_i915_gem_object *obj,
1418 struct intel_ring_buffer *to); 1418 struct intel_ring_buffer *to);
1419void i915_gem_object_move_to_active(struct drm_i915_gem_object *obj, 1419void i915_gem_object_move_to_active(struct drm_i915_gem_object *obj,
1420 struct intel_ring_buffer *ring, 1420 struct intel_ring_buffer *ring);
1421 u32 seqno);
1422 1421
1423int i915_gem_dumb_create(struct drm_file *file_priv, 1422int i915_gem_dumb_create(struct drm_file *file_priv,
1424 struct drm_device *dev, 1423 struct drm_device *dev,
@@ -1436,7 +1435,7 @@ i915_seqno_passed(uint32_t seq1, uint32_t seq2)
1436 return (int32_t)(seq1 - seq2) >= 0; 1435 return (int32_t)(seq1 - seq2) >= 0;
1437} 1436}
1438 1437
1439u32 i915_gem_next_request_seqno(struct intel_ring_buffer *ring); 1438extern int i915_gem_get_seqno(struct drm_device *dev, u32 *seqno);
1440 1439
1441int __must_check i915_gem_object_get_fence(struct drm_i915_gem_object *obj); 1440int __must_check i915_gem_object_get_fence(struct drm_i915_gem_object *obj);
1442int __must_check i915_gem_object_put_fence(struct drm_i915_gem_object *obj); 1441int __must_check i915_gem_object_put_fence(struct drm_i915_gem_object *obj);
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 9be450e7c54f..3b9b250ceac4 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1857,11 +1857,11 @@ i915_gem_object_get_pages(struct drm_i915_gem_object *obj)
1857 1857
1858void 1858void
1859i915_gem_object_move_to_active(struct drm_i915_gem_object *obj, 1859i915_gem_object_move_to_active(struct drm_i915_gem_object *obj,
1860 struct intel_ring_buffer *ring, 1860 struct intel_ring_buffer *ring)
1861 u32 seqno)
1862{ 1861{
1863 struct drm_device *dev = obj->base.dev; 1862 struct drm_device *dev = obj->base.dev;
1864 struct drm_i915_private *dev_priv = dev->dev_private; 1863 struct drm_i915_private *dev_priv = dev->dev_private;
1864 u32 seqno = intel_ring_get_seqno(ring);
1865 1865
1866 BUG_ON(ring == NULL); 1866 BUG_ON(ring == NULL);
1867 obj->ring = ring; 1867 obj->ring = ring;
@@ -1922,26 +1922,54 @@ i915_gem_object_move_to_inactive(struct drm_i915_gem_object *obj)
1922 WARN_ON(i915_verify_lists(dev)); 1922 WARN_ON(i915_verify_lists(dev));
1923} 1923}
1924 1924
1925static u32 1925static int
1926i915_gem_get_seqno(struct drm_device *dev) 1926i915_gem_handle_seqno_wrap(struct drm_device *dev)
1927{ 1927{
1928 drm_i915_private_t *dev_priv = dev->dev_private; 1928 struct drm_i915_private *dev_priv = dev->dev_private;
1929 u32 seqno = dev_priv->next_seqno; 1929 struct intel_ring_buffer *ring;
1930 int ret, i, j;
1930 1931
1931 /* reserve 0 for non-seqno */ 1932 /* The hardware uses various monotonic 32-bit counters, if we
1932 if (++dev_priv->next_seqno == 0) 1933 * detect that they will wraparound we need to idle the GPU
1933 dev_priv->next_seqno = 1; 1934 * and reset those counters.
1935 */
1936 ret = 0;
1937 for_each_ring(ring, dev_priv, i) {
1938 for (j = 0; j < ARRAY_SIZE(ring->sync_seqno); j++)
1939 ret |= ring->sync_seqno[j] != 0;
1940 }
1941 if (ret == 0)
1942 return ret;
1934 1943
1935 return seqno; 1944 ret = i915_gpu_idle(dev);
1945 if (ret)
1946 return ret;
1947
1948 i915_gem_retire_requests(dev);
1949 for_each_ring(ring, dev_priv, i) {
1950 for (j = 0; j < ARRAY_SIZE(ring->sync_seqno); j++)
1951 ring->sync_seqno[j] = 0;
1952 }
1953
1954 return 0;
1936} 1955}
1937 1956
1938u32 1957int
1939i915_gem_next_request_seqno(struct intel_ring_buffer *ring) 1958i915_gem_get_seqno(struct drm_device *dev, u32 *seqno)
1940{ 1959{
1941 if (ring->outstanding_lazy_request == 0) 1960 struct drm_i915_private *dev_priv = dev->dev_private;
1942 ring->outstanding_lazy_request = i915_gem_get_seqno(ring->dev); 1961
1962 /* reserve 0 for non-seqno */
1963 if (dev_priv->next_seqno == 0) {
1964 int ret = i915_gem_handle_seqno_wrap(dev);
1965 if (ret)
1966 return ret;
1943 1967
1944 return ring->outstanding_lazy_request; 1968 dev_priv->next_seqno = 1;
1969 }
1970
1971 *seqno = dev_priv->next_seqno++;
1972 return 0;
1945} 1973}
1946 1974
1947int 1975int
@@ -1952,7 +1980,6 @@ i915_add_request(struct intel_ring_buffer *ring,
1952 drm_i915_private_t *dev_priv = ring->dev->dev_private; 1980 drm_i915_private_t *dev_priv = ring->dev->dev_private;
1953 struct drm_i915_gem_request *request; 1981 struct drm_i915_gem_request *request;
1954 u32 request_ring_position; 1982 u32 request_ring_position;
1955 u32 seqno;
1956 int was_empty; 1983 int was_empty;
1957 int ret; 1984 int ret;
1958 1985
@@ -1971,7 +1998,6 @@ i915_add_request(struct intel_ring_buffer *ring,
1971 if (request == NULL) 1998 if (request == NULL)
1972 return -ENOMEM; 1999 return -ENOMEM;
1973 2000
1974 seqno = i915_gem_next_request_seqno(ring);
1975 2001
1976 /* Record the position of the start of the request so that 2002 /* Record the position of the start of the request so that
1977 * should we detect the updated seqno part-way through the 2003 * should we detect the updated seqno part-way through the
@@ -1980,15 +2006,13 @@ i915_add_request(struct intel_ring_buffer *ring,
1980 */ 2006 */
1981 request_ring_position = intel_ring_get_tail(ring); 2007 request_ring_position = intel_ring_get_tail(ring);
1982 2008
1983 ret = ring->add_request(ring, &seqno); 2009 ret = ring->add_request(ring);
1984 if (ret) { 2010 if (ret) {
1985 kfree(request); 2011 kfree(request);
1986 return ret; 2012 return ret;
1987 } 2013 }
1988 2014
1989 trace_i915_gem_request_add(ring, seqno); 2015 request->seqno = intel_ring_get_seqno(ring);
1990
1991 request->seqno = seqno;
1992 request->ring = ring; 2016 request->ring = ring;
1993 request->tail = request_ring_position; 2017 request->tail = request_ring_position;
1994 request->emitted_jiffies = jiffies; 2018 request->emitted_jiffies = jiffies;
@@ -2006,6 +2030,7 @@ i915_add_request(struct intel_ring_buffer *ring,
2006 spin_unlock(&file_priv->mm.lock); 2030 spin_unlock(&file_priv->mm.lock);
2007 } 2031 }
2008 2032
2033 trace_i915_gem_request_add(ring, request->seqno);
2009 ring->outstanding_lazy_request = 0; 2034 ring->outstanding_lazy_request = 0;
2010 2035
2011 if (!dev_priv->mm.suspended) { 2036 if (!dev_priv->mm.suspended) {
@@ -2022,7 +2047,7 @@ i915_add_request(struct intel_ring_buffer *ring,
2022 } 2047 }
2023 2048
2024 if (out_seqno) 2049 if (out_seqno)
2025 *out_seqno = seqno; 2050 *out_seqno = request->seqno;
2026 return 0; 2051 return 0;
2027} 2052}
2028 2053
@@ -2120,7 +2145,6 @@ void
2120i915_gem_retire_requests_ring(struct intel_ring_buffer *ring) 2145i915_gem_retire_requests_ring(struct intel_ring_buffer *ring)
2121{ 2146{
2122 uint32_t seqno; 2147 uint32_t seqno;
2123 int i;
2124 2148
2125 if (list_empty(&ring->request_list)) 2149 if (list_empty(&ring->request_list))
2126 return; 2150 return;
@@ -2129,10 +2153,6 @@ i915_gem_retire_requests_ring(struct intel_ring_buffer *ring)
2129 2153
2130 seqno = ring->get_seqno(ring, true); 2154 seqno = ring->get_seqno(ring, true);
2131 2155
2132 for (i = 0; i < ARRAY_SIZE(ring->sync_seqno); i++)
2133 if (seqno >= ring->sync_seqno[i])
2134 ring->sync_seqno[i] = 0;
2135
2136 while (!list_empty(&ring->request_list)) { 2156 while (!list_empty(&ring->request_list)) {
2137 struct drm_i915_gem_request *request; 2157 struct drm_i915_gem_request *request;
2138 2158
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index 0e510df80d73..a3f06bcad551 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -410,9 +410,8 @@ static int do_switch(struct i915_hw_context *to)
410 * MI_SET_CONTEXT instead of when the next seqno has completed. 410 * MI_SET_CONTEXT instead of when the next seqno has completed.
411 */ 411 */
412 if (from_obj != NULL) { 412 if (from_obj != NULL) {
413 u32 seqno = i915_gem_next_request_seqno(ring);
414 from_obj->base.read_domains = I915_GEM_DOMAIN_INSTRUCTION; 413 from_obj->base.read_domains = I915_GEM_DOMAIN_INSTRUCTION;
415 i915_gem_object_move_to_active(from_obj, ring, seqno); 414 i915_gem_object_move_to_active(from_obj, ring);
416 /* As long as MI_SET_CONTEXT is serializing, ie. it flushes the 415 /* As long as MI_SET_CONTEXT is serializing, ie. it flushes the
417 * whole damn pipeline, we don't need to explicitly mark the 416 * whole damn pipeline, we don't need to explicitly mark the
418 * object dirty. The only exception is that the context must be 417 * object dirty. The only exception is that the context must be
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index 48e4317e72dc..ee8f97f0539e 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -713,8 +713,7 @@ validate_exec_list(struct drm_i915_gem_exec_object2 *exec,
713 713
714static void 714static void
715i915_gem_execbuffer_move_to_active(struct list_head *objects, 715i915_gem_execbuffer_move_to_active(struct list_head *objects,
716 struct intel_ring_buffer *ring, 716 struct intel_ring_buffer *ring)
717 u32 seqno)
718{ 717{
719 struct drm_i915_gem_object *obj; 718 struct drm_i915_gem_object *obj;
720 719
@@ -726,10 +725,10 @@ i915_gem_execbuffer_move_to_active(struct list_head *objects,
726 obj->base.write_domain = obj->base.pending_write_domain; 725 obj->base.write_domain = obj->base.pending_write_domain;
727 obj->fenced_gpu_access = obj->pending_fenced_gpu_access; 726 obj->fenced_gpu_access = obj->pending_fenced_gpu_access;
728 727
729 i915_gem_object_move_to_active(obj, ring, seqno); 728 i915_gem_object_move_to_active(obj, ring);
730 if (obj->base.write_domain) { 729 if (obj->base.write_domain) {
731 obj->dirty = 1; 730 obj->dirty = 1;
732 obj->last_write_seqno = seqno; 731 obj->last_write_seqno = intel_ring_get_seqno(ring);
733 if (obj->pin_count) /* check for potential scanout */ 732 if (obj->pin_count) /* check for potential scanout */
734 intel_mark_fb_busy(obj); 733 intel_mark_fb_busy(obj);
735 } 734 }
@@ -789,7 +788,6 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
789 struct intel_ring_buffer *ring; 788 struct intel_ring_buffer *ring;
790 u32 ctx_id = i915_execbuffer2_get_context_id(*args); 789 u32 ctx_id = i915_execbuffer2_get_context_id(*args);
791 u32 exec_start, exec_len; 790 u32 exec_start, exec_len;
792 u32 seqno;
793 u32 mask; 791 u32 mask;
794 u32 flags; 792 u32 flags;
795 int ret, mode, i; 793 int ret, mode, i;
@@ -994,22 +992,6 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
994 if (ret) 992 if (ret)
995 goto err; 993 goto err;
996 994
997 seqno = i915_gem_next_request_seqno(ring);
998 for (i = 0; i < ARRAY_SIZE(ring->sync_seqno); i++) {
999 if (seqno < ring->sync_seqno[i]) {
1000 /* The GPU can not handle its semaphore value wrapping,
1001 * so every billion or so execbuffers, we need to stall
1002 * the GPU in order to reset the counters.
1003 */
1004 ret = i915_gpu_idle(dev);
1005 if (ret)
1006 goto err;
1007 i915_gem_retire_requests(dev);
1008
1009 BUG_ON(ring->sync_seqno[i]);
1010 }
1011 }
1012
1013 ret = i915_switch_context(ring, file, ctx_id); 995 ret = i915_switch_context(ring, file, ctx_id);
1014 if (ret) 996 if (ret)
1015 goto err; 997 goto err;
@@ -1035,8 +1017,6 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
1035 goto err; 1017 goto err;
1036 } 1018 }
1037 1019
1038 trace_i915_gem_ring_dispatch(ring, seqno, flags);
1039
1040 exec_start = batch_obj->gtt_offset + args->batch_start_offset; 1020 exec_start = batch_obj->gtt_offset + args->batch_start_offset;
1041 exec_len = args->batch_len; 1021 exec_len = args->batch_len;
1042 if (cliprects) { 1022 if (cliprects) {
@@ -1060,7 +1040,9 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
1060 goto err; 1040 goto err;
1061 } 1041 }
1062 1042
1063 i915_gem_execbuffer_move_to_active(&objects, ring, seqno); 1043 trace_i915_gem_ring_dispatch(ring, intel_ring_get_seqno(ring), flags);
1044
1045 i915_gem_execbuffer_move_to_active(&objects, ring);
1064 i915_gem_execbuffer_retire_commands(dev, file, ring); 1046 i915_gem_execbuffer_retire_commands(dev, file, ring);
1065 1047
1066err: 1048err:
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 987eb5fdaf39..e4682cdc00b0 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -555,12 +555,11 @@ static void render_ring_cleanup(struct intel_ring_buffer *ring)
555 555
556static void 556static void
557update_mboxes(struct intel_ring_buffer *ring, 557update_mboxes(struct intel_ring_buffer *ring,
558 u32 seqno, 558 u32 mmio_offset)
559 u32 mmio_offset)
560{ 559{
561 intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1)); 560 intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1));
562 intel_ring_emit(ring, mmio_offset); 561 intel_ring_emit(ring, mmio_offset);
563 intel_ring_emit(ring, seqno); 562 intel_ring_emit(ring, ring->outstanding_lazy_request);
564} 563}
565 564
566/** 565/**
@@ -573,8 +572,7 @@ update_mboxes(struct intel_ring_buffer *ring,
573 * This acts like a signal in the canonical semaphore. 572 * This acts like a signal in the canonical semaphore.
574 */ 573 */
575static int 574static int
576gen6_add_request(struct intel_ring_buffer *ring, 575gen6_add_request(struct intel_ring_buffer *ring)
577 u32 *seqno)
578{ 576{
579 u32 mbox1_reg; 577 u32 mbox1_reg;
580 u32 mbox2_reg; 578 u32 mbox2_reg;
@@ -587,13 +585,11 @@ gen6_add_request(struct intel_ring_buffer *ring,
587 mbox1_reg = ring->signal_mbox[0]; 585 mbox1_reg = ring->signal_mbox[0];
588 mbox2_reg = ring->signal_mbox[1]; 586 mbox2_reg = ring->signal_mbox[1];
589 587
590 *seqno = i915_gem_next_request_seqno(ring); 588 update_mboxes(ring, mbox1_reg);
591 589 update_mboxes(ring, mbox2_reg);
592 update_mboxes(ring, *seqno, mbox1_reg);
593 update_mboxes(ring, *seqno, mbox2_reg);
594 intel_ring_emit(ring, MI_STORE_DWORD_INDEX); 590 intel_ring_emit(ring, MI_STORE_DWORD_INDEX);
595 intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); 591 intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
596 intel_ring_emit(ring, *seqno); 592 intel_ring_emit(ring, ring->outstanding_lazy_request);
597 intel_ring_emit(ring, MI_USER_INTERRUPT); 593 intel_ring_emit(ring, MI_USER_INTERRUPT);
598 intel_ring_advance(ring); 594 intel_ring_advance(ring);
599 595
@@ -650,10 +646,8 @@ do { \
650} while (0) 646} while (0)
651 647
652static int 648static int
653pc_render_add_request(struct intel_ring_buffer *ring, 649pc_render_add_request(struct intel_ring_buffer *ring)
654 u32 *result)
655{ 650{
656 u32 seqno = i915_gem_next_request_seqno(ring);
657 struct pipe_control *pc = ring->private; 651 struct pipe_control *pc = ring->private;
658 u32 scratch_addr = pc->gtt_offset + 128; 652 u32 scratch_addr = pc->gtt_offset + 128;
659 int ret; 653 int ret;
@@ -674,7 +668,7 @@ pc_render_add_request(struct intel_ring_buffer *ring,
674 PIPE_CONTROL_WRITE_FLUSH | 668 PIPE_CONTROL_WRITE_FLUSH |
675 PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE); 669 PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE);
676 intel_ring_emit(ring, pc->gtt_offset | PIPE_CONTROL_GLOBAL_GTT); 670 intel_ring_emit(ring, pc->gtt_offset | PIPE_CONTROL_GLOBAL_GTT);
677 intel_ring_emit(ring, seqno); 671 intel_ring_emit(ring, ring->outstanding_lazy_request);
678 intel_ring_emit(ring, 0); 672 intel_ring_emit(ring, 0);
679 PIPE_CONTROL_FLUSH(ring, scratch_addr); 673 PIPE_CONTROL_FLUSH(ring, scratch_addr);
680 scratch_addr += 128; /* write to separate cachelines */ 674 scratch_addr += 128; /* write to separate cachelines */
@@ -693,11 +687,10 @@ pc_render_add_request(struct intel_ring_buffer *ring,
693 PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE | 687 PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE |
694 PIPE_CONTROL_NOTIFY); 688 PIPE_CONTROL_NOTIFY);
695 intel_ring_emit(ring, pc->gtt_offset | PIPE_CONTROL_GLOBAL_GTT); 689 intel_ring_emit(ring, pc->gtt_offset | PIPE_CONTROL_GLOBAL_GTT);
696 intel_ring_emit(ring, seqno); 690 intel_ring_emit(ring, ring->outstanding_lazy_request);
697 intel_ring_emit(ring, 0); 691 intel_ring_emit(ring, 0);
698 intel_ring_advance(ring); 692 intel_ring_advance(ring);
699 693
700 *result = seqno;
701 return 0; 694 return 0;
702} 695}
703 696
@@ -885,25 +878,20 @@ bsd_ring_flush(struct intel_ring_buffer *ring,
885} 878}
886 879
887static int 880static int
888i9xx_add_request(struct intel_ring_buffer *ring, 881i9xx_add_request(struct intel_ring_buffer *ring)
889 u32 *result)
890{ 882{
891 u32 seqno;
892 int ret; 883 int ret;
893 884
894 ret = intel_ring_begin(ring, 4); 885 ret = intel_ring_begin(ring, 4);
895 if (ret) 886 if (ret)
896 return ret; 887 return ret;
897 888
898 seqno = i915_gem_next_request_seqno(ring);
899
900 intel_ring_emit(ring, MI_STORE_DWORD_INDEX); 889 intel_ring_emit(ring, MI_STORE_DWORD_INDEX);
901 intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); 890 intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
902 intel_ring_emit(ring, seqno); 891 intel_ring_emit(ring, ring->outstanding_lazy_request);
903 intel_ring_emit(ring, MI_USER_INTERRUPT); 892 intel_ring_emit(ring, MI_USER_INTERRUPT);
904 intel_ring_advance(ring); 893 intel_ring_advance(ring);
905 894
906 *result = seqno;
907 return 0; 895 return 0;
908} 896}
909 897
@@ -1110,6 +1098,7 @@ static int intel_init_ring_buffer(struct drm_device *dev,
1110 INIT_LIST_HEAD(&ring->active_list); 1098 INIT_LIST_HEAD(&ring->active_list);
1111 INIT_LIST_HEAD(&ring->request_list); 1099 INIT_LIST_HEAD(&ring->request_list);
1112 ring->size = 32 * PAGE_SIZE; 1100 ring->size = 32 * PAGE_SIZE;
1101 memset(ring->sync_seqno, 0, sizeof(ring->sync_seqno));
1113 1102
1114 init_waitqueue_head(&ring->irq_queue); 1103 init_waitqueue_head(&ring->irq_queue);
1115 1104
@@ -1338,6 +1327,15 @@ int intel_wait_ring_buffer(struct intel_ring_buffer *ring, int n)
1338 return -EBUSY; 1327 return -EBUSY;
1339} 1328}
1340 1329
1330static int
1331intel_ring_alloc_seqno(struct intel_ring_buffer *ring)
1332{
1333 if (ring->outstanding_lazy_request)
1334 return 0;
1335
1336 return i915_gem_get_seqno(ring->dev, &ring->outstanding_lazy_request);
1337}
1338
1341int intel_ring_begin(struct intel_ring_buffer *ring, 1339int intel_ring_begin(struct intel_ring_buffer *ring,
1342 int num_dwords) 1340 int num_dwords)
1343{ 1341{
@@ -1349,6 +1347,11 @@ int intel_ring_begin(struct intel_ring_buffer *ring,
1349 if (ret) 1347 if (ret)
1350 return ret; 1348 return ret;
1351 1349
1350 /* Preallocate the olr before touching the ring */
1351 ret = intel_ring_alloc_seqno(ring);
1352 if (ret)
1353 return ret;
1354
1352 if (unlikely(ring->tail + n > ring->effective_size)) { 1355 if (unlikely(ring->tail + n > ring->effective_size)) {
1353 ret = intel_wrap_ring_buffer(ring); 1356 ret = intel_wrap_ring_buffer(ring);
1354 if (unlikely(ret)) 1357 if (unlikely(ret))
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index 5af65b89765f..0e613026d003 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -70,8 +70,7 @@ struct intel_ring_buffer {
70 int __must_check (*flush)(struct intel_ring_buffer *ring, 70 int __must_check (*flush)(struct intel_ring_buffer *ring,
71 u32 invalidate_domains, 71 u32 invalidate_domains,
72 u32 flush_domains); 72 u32 flush_domains);
73 int (*add_request)(struct intel_ring_buffer *ring, 73 int (*add_request)(struct intel_ring_buffer *ring);
74 u32 *seqno);
75 /* Some chipsets are not quite as coherent as advertised and need 74 /* Some chipsets are not quite as coherent as advertised and need
76 * an expensive kick to force a true read of the up-to-date seqno. 75 * an expensive kick to force a true read of the up-to-date seqno.
77 * However, the up-to-date seqno is not always required and the last 76 * However, the up-to-date seqno is not always required and the last
@@ -205,7 +204,6 @@ static inline void intel_ring_emit(struct intel_ring_buffer *ring,
205 204
206void intel_ring_advance(struct intel_ring_buffer *ring); 205void intel_ring_advance(struct intel_ring_buffer *ring);
207 206
208u32 intel_ring_get_seqno(struct intel_ring_buffer *ring);
209int intel_ring_flush_all_caches(struct intel_ring_buffer *ring); 207int intel_ring_flush_all_caches(struct intel_ring_buffer *ring);
210int intel_ring_invalidate_all_caches(struct intel_ring_buffer *ring); 208int intel_ring_invalidate_all_caches(struct intel_ring_buffer *ring);
211 209
@@ -221,6 +219,12 @@ static inline u32 intel_ring_get_tail(struct intel_ring_buffer *ring)
221 return ring->tail; 219 return ring->tail;
222} 220}
223 221
222static inline u32 intel_ring_get_seqno(struct intel_ring_buffer *ring)
223{
224 BUG_ON(ring->outstanding_lazy_request == 0);
225 return ring->outstanding_lazy_request;
226}
227
224static inline void i915_trace_irq_get(struct intel_ring_buffer *ring, u32 seqno) 228static inline void i915_trace_irq_get(struct intel_ring_buffer *ring, u32 seqno)
225{ 229{
226 if (ring->trace_irq_seqno == 0 && ring->irq_get(ring)) 230 if (ring->trace_irq_seqno == 0 && ring->irq_get(ring))