[Intel-gfx] [PATCH 2/3] drm/i915: Introduce intel_ring_begin_cacheline_safe()
ville.syrjala at linux.intel.com
ville.syrjala at linux.intel.com
Tue Feb 11 14:55:49 CET 2014
From: Ville Syrjälä <ville.syrjala at linux.intel.com>
Add a special variant of intel_ring_begin() which allows the caller to
specify that a certain subset of the emitted dwords must fall within
a single cacheline.
intel_ring_begin_cacheline_safe() will return the number of extra dwords
that need to be emitted by the caller to produce the desired result.
Cc: Bjoern C <lkml at call-home.ch>
Cc: Alexandru DAMIAN <alexandru.damian at intel.com>
Cc: Enrico Tagliavini <enrico.tagliavini at gmail.com>
Signed-off-by: Ville Syrjälä <ville.syrjala at linux.intel.com>
---
drivers/gpu/drm/i915/intel_ringbuffer.c | 67 +++++++++++++++++++++++++++++++++
drivers/gpu/drm/i915/intel_ringbuffer.h | 5 +++
2 files changed, 72 insertions(+)
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index a2bd533..87f5cee 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -1647,6 +1647,73 @@ int intel_ring_begin(struct intel_ring_buffer *ring,
ring->tail + bytes > ring->effective_size);
}
+static bool range_within_cacheline(int offset, int start, int end)
+{
+ return ((offset + start) & ~63) == ((offset + end - 1) & ~63);
+}
+
+/**
+ * intel_ring_begin_cacheline_safe - Allocate ring space while
+ * making sure a specific range of dwords lands inside a single
+ * cacheline.
+ *
+ * @ring: the ring buffer
+ * @first_cl_dword: first special dword
+ * @num_cl_dwords: how many dwords after @first_cl_dword must
+ * be within the same cacheline.
+ * @num_dwords: total number of dwords
+ * @num_extra_dwords: return number of extra dwords
+ *
+ * Allocate ring space line intel_ring_begin but make sure
+ * @num_cl_dwords dwords starting at @first_cl_dword all
+ * end up within the same cacheline. @num_extra_dwords will
+ * indicate how many extra dwords have to emitted. The extra
+ * dwords must be emitted at or before the original
+ * @first_cl_dword position.
+ */
+int intel_ring_begin_cacheline_safe(struct intel_ring_buffer *ring,
+ int first_cl_dword,
+ int num_cl_dwords,
+ int num_dwords,
+ int *num_extra_dwords)
+{
+ int start = first_cl_dword * sizeof(uint32_t);
+ int end = start + num_cl_dwords * sizeof(uint32_t);
+ int bytes = num_dwords * sizeof(uint32_t);
+ int tail = ring->tail;
+ int extra = 0;
+
+ if (WARN_ON(end - start > 64))
+ return -EINVAL;
+
+ /* Need to wrap in any case? */
+ if (tail + bytes > ring->effective_size)
+ tail = 0;
+
+ if (!range_within_cacheline(tail, start, end)) {
+ extra = 64 - ((tail + start) & 63);
+
+ /* Need to wrap due to the extra dwords? */
+ if (tail + extra + bytes > ring->effective_size) {
+ tail = 0;
+
+ /* Recalculate extra after the wrap */
+ extra = 0;
+ if (!range_within_cacheline(tail, start, end))
+ extra = 64 - ((tail + start) & 63);
+ }
+ }
+
+ /* Sanity checks. These should never happen. */
+ if (WARN_ON(!range_within_cacheline(tail + extra, start, end) ||
+ tail + extra + bytes > ring->effective_size))
+ return -EINVAL;
+
+ *num_extra_dwords = extra / sizeof(uint32_t);
+
+ return __intel_ring_begin(ring, extra + bytes, tail != ring->tail);
+}
+
void intel_ring_init_seqno(struct intel_ring_buffer *ring, u32 seqno)
{
struct drm_i915_private *dev_priv = ring->dev->dev_private;
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index 38c757e..e48e81e 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -235,6 +235,11 @@ intel_write_status_page(struct intel_ring_buffer *ring,
void intel_cleanup_ring_buffer(struct intel_ring_buffer *ring);
int __must_check intel_ring_begin(struct intel_ring_buffer *ring, int n);
+int __must_check intel_ring_begin_cacheline_safe(struct intel_ring_buffer *ring,
+ int first_cl_dword,
+ int num_cl_dwords,
+ int num_dwords,
+ int *num_extra_dwords);
static inline void intel_ring_emit(struct intel_ring_buffer *ring,
u32 data)
{
--
1.8.3.2
More information about the Intel-gfx
mailing list