Re: [PATCH 43/49] drm/i915/bdw: Handle context switch events

Damien Lespiau
2014-04-03T14:25:01Z

On Thu, Mar 27, 2014 at 06:00:12PM +0000, oscar.mateo@intel.com wrote:
> +void gen8_handle_context_events(struct intel_engine *ring)
> +{
> + struct drm_i915_private *dev_priv = ring->dev->dev_private;
> + u32 status_pointer;
> + u8 read_pointer;
> + u8 write_pointer;
> + u32 status;
> + u32 status_id;
> + u32 submit_contexts = 0;
> +
> + status_pointer = I915_READ(RING_CONTEXT_STATUS_PTR(ring));
> +
> + read_pointer = ring->next_context_status_buffer;
> + write_pointer = status_pointer & 0x07;
> + if (read_pointer > write_pointer)
> + write_pointer += 6;
> +
> + spin_lock(&ring->execlist_lock);
> +
> + while (read_pointer < write_pointer) {
> + read_pointer++;
> + status = I915_READ(RING_CONTEXT_STATUS_BUF(ring) +
> + (read_pointer % 6) * 8);
> + status_id = I915_READ(RING_CONTEXT_STATUS_BUF(ring) +
> + (read_pointer % 6) * 8 + 4);
> +
> + if (status & GEN8_CTX_STATUS_ELEMENT_SWITCH) {
> + if (check_remove_request(ring, status_id))
> + submit_contexts++;
> + } else if (status & GEN8_CTX_STATUS_COMPLETE) {
> + if (check_remove_request(ring, status_id))
> + submit_contexts++;
> + }
> + }
> +
> + if (submit_contexts != 0)
> + gen8_switch_context_unqueue(ring);
> +
> + spin_unlock(&ring->execlist_lock);
> +
> + WARN(submit_contexts > 2, "More than two context complete events?\n");
> + ring->next_context_status_buffer = write_pointer % 6;
> +}

I'm a bit suprised that we never update the read pointer in the
CONTEXT_STATUS_PTR when we consume entries from CONTEXT_STATUS_BUF.

Are we sure this field isn't used by hw at all to figure out if the
circular buffer has some free space?

--
Damien