[Intel-gfx] [PATCH] RFC drm/i915: Slaughter the thundering i915_wait_request herd
Chris Wilson
chris at chris-wilson.co.uk
Mon Nov 2 12:58:30 PST 2015
On Mon, Nov 02, 2015 at 03:28:22PM +0000, Chris Wilson wrote:
> That should keep the worker alive for a further 10 jiffies, hopefully
> long enough for the next wait to occur. The cost is that it keeps the
> interrupt asserted (and to avoid that requires a little rearrangment and
> probably a dedicated kthread for each ring).
Slightly better version that avoids keeping the interrupt active when
not required:
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 8d1e0a5e19a1..3e810c9ea3cb 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1148,7 +1148,7 @@ static int __i915_spin_request(struct drm_i915_gem_request *req)
{
unsigned long timeout;
- if (i915_gem_request_get_ring(req)->irq_refcount)
+ if (waitqueue_active(&i915_gem_request_get_ring(req)->irq_queue))
return -EBUSY;
if (req->ring->seqno_barrier)
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 21017daecb90..9ed063a85c05 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -68,9 +68,11 @@ static void intel_engine_irq_wakeup(struct work_struct *work)
{
struct intel_engine_cs *engine =
container_of(work, struct intel_engine_cs, irq_work);
- const bool noirq = !__irq_enable(engine);
+ bool noirq;
DEFINE_WAIT(wait);
+restart:
+ noirq = !__irq_enable(engine);
for (;;) {
struct timer_list timer;
struct drm_i915_gem_request *request;
@@ -142,9 +144,14 @@ static void intel_engine_irq_wakeup(struct work_struct *work)
destroy_timer_on_stack(&timer);
}
}
- finish_wait(&engine->irq_queue, &wait);
if (!noirq)
engine->irq_put(engine);
+
+ prepare_to_wait(&engine->irq_queue, &wait, TASK_UNINTERRUPTIBLE);
+ if (schedule_timeout(msecs_to_jiffies_timeout(20)) > 0)
+ goto restart;
+
+ finish_wait(&engine->irq_queue, &wait);
}
void intel_engine_init_wakeups(struct intel_engine_cs *engine)
@@ -163,8 +170,10 @@ void intel_engine_add_wakeup(struct drm_i915_gem_request *request)
struct rb_node **p, *parent;
bool first;
- if (RB_EMPTY_ROOT(&engine->irq_requests))
+ if (RB_EMPTY_ROOT(&engine->irq_requests)) {
schedule_work(&engine->irq_work);
+ wake_up_all(&engine->irq_queue);
+ }
init_waitqueue_head(&request->wait);
--
Chris Wilson, Intel Open Source Technology Centre
More information about the Intel-gfx
mailing list