History

drm/i915: Implement workaround for broken CS tlb on i830/845

Now that Chris Wilson demonstrated that the key for stability on early gen 2 is to simple _never_ exchange the physical backing storage of batch buffers I've tried a stab at a kernel solution. Doesn't look too nefarious imho, now that I don't try to be too clever for my own good any more. v2: After discussing the various techniques, we've decided to always blit batches on the suspect devices, but allow userspace to opt out of the kernel workaround assume full responsibility for providing coherent batches. The principal reason is that avoiding the blit does improve performance in a few key microbenchmarks and also in cairo-trace replays.

Daniel Vetter committed 13 years ago

Commit b45305f1 parent 6547fbd7 files · +100 −8Browse files

Unified · Split

7 files
  1. drivers/gpu/drm/i915/i915_dma.c +3 −0
  2. drivers/gpu/drm/i915/i915_drv.h +4 −0
  3. drivers/gpu/drm/i915/i915_gem_execbuffer.c +2 −0
  4. drivers/gpu/drm/i915/i915_irq.c +12 −0
  5. drivers/gpu/drm/i915/intel_ringbuffer.c +68 −8
  6. drivers/gpu/drm/i915/intel_ringbuffer.h +1 −0
  7. include/uapi/drm/i915_drm.h +10 −0
drivers/gpu/drm/i915/i915_dma.c+3−0
@@ -989,6 +989,9 @@ static int i915_getparam(struct drm_device *dev, void *data, · 988 unmodified lines
989989 case I915_PARAM_HAS_SECURE_BATCHES:
990990 value = capable(CAP_SYS_ADMIN);
991991 break;
992+ case I915_PARAM_HAS_PINNED_BATCHES:
993+ value = 1;
994+ break;
992995 default:
993996 DRM_DEBUG_DRIVER("Unknown parameter %d\n",
994997 param->param);
drivers/gpu/drm/i915/i915_drv.h+4−0
@@ -1100,6 +1100,7 @@ struct drm_i915_gem_object { · 1099 unmodified lines
11001100 */
11011101 atomic_t pending_flip;
11021102 };
1103+#define to_gem_object(obj) (&((struct drm_i915_gem_object *)(obj))->base)
11031104
11041105 #define to_intel_bo(x) container_of(x, struct drm_i915_gem_object, base)
11051106
@@ -1199,6 +1200,9 @@ struct drm_i915_file_private { · 93 unmodified lines
11991200 #define HAS_OVERLAY(dev) (INTEL_INFO(dev)->has_overlay)
12001201 #define OVERLAY_NEEDS_PHYSICAL(dev) (INTEL_INFO(dev)->overlay_needs_physical)
12011202
1203+/* Early gen2 have a totally busted CS tlb and require pinned batches. */
1204+#define HAS_BROKEN_CS_TLB(dev) (IS_I830(dev) || IS_845G(dev))
1205+
12021206 /* With the 945 and later, Y tiling got adjusted so that it was 32 128-byte
12031207 * rows, which changed the alignment requirements and fence programming.
12041208 */
drivers/gpu/drm/i915/i915_gem_execbuffer.c+2−0
@@ -808,6 +808,8 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, · 807 unmodified lines
808808
809809 flags |= I915_DISPATCH_SECURE;
810810 }
811+ if (args->flags & I915_EXEC_IS_PINNED)
812+ flags |= I915_DISPATCH_PINNED;
811813
812814 switch (args->flags & I915_EXEC_RING_MASK) {
813815 case I915_EXEC_DEFAULT:
drivers/gpu/drm/i915/i915_irq.c+12−0
@@ -1087,6 +1087,18 @@ i915_error_first_batchbuffer(struct drm_i915_private *dev_priv, · 1086 unmodified lines
10871087 if (!ring->get_seqno)
10881088 return NULL;
10891089
1090+ if (HAS_BROKEN_CS_TLB(dev_priv->dev)) {
1091+ u32 acthd = I915_READ(ACTHD);
1092+
1093+ if (WARN_ON(ring->id != RCS))
1094+ return NULL;
1095+
1096+ obj = ring->private;
1097+ if (acthd >= obj->gtt_offset &&
1098+ acthd < obj->gtt_offset + obj->base.size)
1099+ return i915_error_object_create(dev_priv, obj);
1100+ }
1101+
10901102 seqno = ring->get_seqno(ring, false);
10911103 list_for_each_entry(obj, &dev_priv->mm.active_list, mm_list) {
10921104 if (obj->ring != ring)
drivers/gpu/drm/i915/intel_ringbuffer.c+68−8
@@ -547,9 +547,14 @@ static int init_render_ring(struct intel_ring_buffer *ring) · 546 unmodified lines
547547
548548 static void render_ring_cleanup(struct intel_ring_buffer *ring)
549549 {
550+ struct drm_device *dev = ring->dev;
551+
550552 if (!ring->private)
551553 return;
552554
555+ if (HAS_BROKEN_CS_TLB(dev))
556+ drm_gem_object_unreference(to_gem_object(ring->private));
557+
553558 cleanup_pipe_control(ring);
554559 }
555560
@@ -969,6 +974,8 @@ i965_dispatch_execbuffer(struct intel_ring_buffer *ring, · 413 unmodified lines
969974 return 0;
970975 }
971976
977+/* Just userspace ABI convention to limit the wa batch bo to a resonable size */
978+#define I830_BATCH_LIMIT (256*1024)
972979 static int
973980 i830_dispatch_execbuffer(struct intel_ring_buffer *ring,
974981 u32 offset, u32 len,
@@ -976,15 +983,47 @@ i830_dispatch_execbuffer(struct intel_ring_buffer *ring, · 1 unmodified line
976983 {
977984 int ret;
978985
979− ret = intel_ring_begin(ring, 4);
980− if (ret)
981− return ret;
986+ if (flags & I915_DISPATCH_PINNED) {
987+ ret = intel_ring_begin(ring, 4);
988+ if (ret)
989+ return ret;
982990
983− intel_ring_emit(ring, MI_BATCH_BUFFER);
984− intel_ring_emit(ring, offset | (flags & I915_DISPATCH_SECURE ? 0 : MI_BATCH_NON_SECURE));
985− intel_ring_emit(ring, offset + len - 8);
986− intel_ring_emit(ring, 0);
987− intel_ring_advance(ring);
991+ intel_ring_emit(ring, MI_BATCH_BUFFER);
992+ intel_ring_emit(ring, offset | (flags & I915_DISPATCH_SECURE ? 0 : MI_BATCH_NON_SECURE));
993+ intel_ring_emit(ring, offset + len - 8);
994+ intel_ring_emit(ring, MI_NOOP);
995+ intel_ring_advance(ring);
996+ } else {
997+ struct drm_i915_gem_object *obj = ring->private;
998+ u32 cs_offset = obj->gtt_offset;
999+
1000+ if (len > I830_BATCH_LIMIT)
1001+ return -ENOSPC;
1002+
1003+ ret = intel_ring_begin(ring, 9+3);
1004+ if (ret)
1005+ return ret;
1006+ /* Blit the batch (which has now all relocs applied) to the stable batch
1007+ * scratch bo area (so that the CS never stumbles over its tlb
1008+ * invalidation bug) ... */
1009+ intel_ring_emit(ring, XY_SRC_COPY_BLT_CMD |
1010+ XY_SRC_COPY_BLT_WRITE_ALPHA |
1011+ XY_SRC_COPY_BLT_WRITE_RGB);
1012+ intel_ring_emit(ring, BLT_DEPTH_32 | BLT_ROP_GXCOPY | 4096);
1013+ intel_ring_emit(ring, 0);
1014+ intel_ring_emit(ring, (DIV_ROUND_UP(len, 4096) << 16) | 1024);
1015+ intel_ring_emit(ring, cs_offset);
1016+ intel_ring_emit(ring, 0);
1017+ intel_ring_emit(ring, 4096);
1018+ intel_ring_emit(ring, offset);
1019+ intel_ring_emit(ring, MI_FLUSH);
1020+
1021+ /* ... and execute it. */
1022+ intel_ring_emit(ring, MI_BATCH_BUFFER);
1023+ intel_ring_emit(ring, cs_offset | (flags & I915_DISPATCH_SECURE ? 0 : MI_BATCH_NON_SECURE));
1024+ intel_ring_emit(ring, cs_offset + len - 8);
1025+ intel_ring_advance(ring);
1026+ }
9881027
9891028 return 0;
9901029 }
@@ -1596,6 +1635,27 @@ int intel_init_render_ring_buffer(struct drm_device *dev) · 605 unmodified lines
15961635 ring->init = init_render_ring;
15971636 ring->cleanup = render_ring_cleanup;
15981637
1638+ /* Workaround batchbuffer to combat CS tlb bug. */
1639+ if (HAS_BROKEN_CS_TLB(dev)) {
1640+ struct drm_i915_gem_object *obj;
1641+ int ret;
1642+
1643+ obj = i915_gem_alloc_object(dev, I830_BATCH_LIMIT);
1644+ if (obj == NULL) {
1645+ DRM_ERROR("Failed to allocate batch bo\n");
1646+ return -ENOMEM;
1647+ }
1648+
1649+ ret = i915_gem_object_pin(obj, 0, true, false);
1650+ if (ret != 0) {
1651+ drm_gem_object_unreference(&obj->base);
1652+ DRM_ERROR("Failed to ping batch bo\n");
1653+ return ret;
1654+ }
1655+
1656+ ring->private = obj;
1657+ }
1658+
15991659 return intel_init_ring_buffer(dev, ring);
16001660 }
16011661
drivers/gpu/drm/i915/intel_ringbuffer.h+1−0
@@ -94,6 +94,7 @@ struct intel_ring_buffer { · 93 unmodified lines
9494 u32 offset, u32 length,
9595 unsigned flags);
9696 #define I915_DISPATCH_SECURE 0x1
97+#define I915_DISPATCH_PINNED 0x2
9798 void (*cleanup)(struct intel_ring_buffer *ring);
9899 int (*sync_to)(struct intel_ring_buffer *ring,
99100 struct intel_ring_buffer *to,
include/uapi/drm/i915_drm.h+10−0
@@ -307,6 +307,7 @@ typedef struct drm_i915_irq_wait { · 306 unmodified lines
307307 #define I915_PARAM_HAS_PRIME_VMAP_FLUSH 21
308308 #define I915_PARAM_RSVD_FOR_FUTURE_USE 22
309309 #define I915_PARAM_HAS_SECURE_BATCHES 23
310+#define I915_PARAM_HAS_PINNED_BATCHES 24
310311
311312 typedef struct drm_i915_getparam {
312313 int param;
@@ -677,6 +678,15 @@ struct drm_i915_gem_execbuffer2 { · 364 unmodified lines
677678 */
678679 #define I915_EXEC_SECURE (1<<9)
679680
681+/** Inform the kernel that the batch is and will always be pinned. This
682+ * negates the requirement for a workaround to be performed to avoid
683+ * an incoherent CS (such as can be found on 830/845). If this flag is
684+ * not passed, the kernel will endeavour to make sure the batch is
685+ * coherent with the CS before execution. If this flag is passed,
686+ * userspace assumes the responsibility for ensuring the same.
687+ */
688+#define I915_EXEC_IS_PINNED (1<<10)
689+
680690 #define I915_EXEC_CONTEXT_ID_MASK (0xffffffff)
681691 #define i915_execbuffer2_set_context_id(eb2, context) \
682692 (eb2).rsvd1 = context & I915_EXEC_CONTEXT_ID_MASK