Commit 8ea397fa authored by Chris Wilson's avatar Chris Wilson

drm/i915/execlists: Process one CSB update at a time

In the next patch, we will process the CSB events directly from the
submission path, rather than only after a CS interrupt. Hence, we will
no longer have the need for a loop until the has-interrupt bit is clear,
and in the meantime can remove that small optimisation.

v2: Tvrtko pointed out it was safer to unconditionally kick the tasklet
after each irq, when assuming that the tasklet is called for each irq.
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Reviewed-by: default avatarTvrtko Ursulin <tvrtko.ursulin@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180628201211.13837-4-chris@chris-wilson.co.uk
parent d8857d54
...@@ -1497,9 +1497,10 @@ gen8_cs_irq_handler(struct intel_engine_cs *engine, u32 iir) ...@@ -1497,9 +1497,10 @@ gen8_cs_irq_handler(struct intel_engine_cs *engine, u32 iir)
bool tasklet = false; bool tasklet = false;
if (iir & GT_CONTEXT_SWITCH_INTERRUPT) { if (iir & GT_CONTEXT_SWITCH_INTERRUPT) {
if (READ_ONCE(engine->execlists.active)) if (READ_ONCE(engine->execlists.active)) {
tasklet = !test_and_set_bit(ENGINE_IRQ_EXECLIST, set_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted);
&engine->irq_posted); tasklet = true;
}
} }
if (iir & GT_RENDER_USER_INTERRUPT) { if (iir & GT_RENDER_USER_INTERRUPT) {
......
...@@ -955,23 +955,20 @@ static void process_csb(struct intel_engine_cs *engine) ...@@ -955,23 +955,20 @@ static void process_csb(struct intel_engine_cs *engine)
struct intel_engine_execlists * const execlists = &engine->execlists; struct intel_engine_execlists * const execlists = &engine->execlists;
struct execlist_port *port = execlists->port; struct execlist_port *port = execlists->port;
struct drm_i915_private *i915 = engine->i915; struct drm_i915_private *i915 = engine->i915;
bool fw = false;
do {
/* The HWSP contains a (cacheable) mirror of the CSB */ /* The HWSP contains a (cacheable) mirror of the CSB */
const u32 *buf = const u32 *buf =
&engine->status_page.page_addr[I915_HWS_CSB_BUF0_INDEX]; &engine->status_page.page_addr[I915_HWS_CSB_BUF0_INDEX];
unsigned int head, tail; unsigned int head, tail;
bool fw = false;
/* Clear before reading to catch new interrupts */ /* Clear before reading to catch new interrupts */
clear_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted); clear_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted);
smp_mb__after_atomic(); smp_mb__after_atomic();
if (unlikely(execlists->csb_use_mmio)) { if (unlikely(execlists->csb_use_mmio)) {
if (!fw) {
intel_uncore_forcewake_get(i915, execlists->fw_domains); intel_uncore_forcewake_get(i915, execlists->fw_domains);
fw = true; fw = true;
}
buf = (u32 * __force) buf = (u32 * __force)
(i915->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_BUF_LO(engine, 0))); (i915->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_BUF_LO(engine, 0)));
...@@ -1114,7 +1111,6 @@ static void process_csb(struct intel_engine_cs *engine) ...@@ -1114,7 +1111,6 @@ static void process_csb(struct intel_engine_cs *engine)
writel(_MASKED_FIELD(GEN8_CSB_READ_PTR_MASK, head << 8), writel(_MASKED_FIELD(GEN8_CSB_READ_PTR_MASK, head << 8),
i915->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_PTR(engine))); i915->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_PTR(engine)));
} }
} while (test_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted));
if (unlikely(fw)) if (unlikely(fw))
intel_uncore_forcewake_put(i915, execlists->fw_domains); intel_uncore_forcewake_put(i915, execlists->fw_domains);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment