Blob Blame History Raw
From: Chris Wilson <chris@chris-wilson.co.uk>
Date: Mon, 15 Jan 2018 09:06:42 +0000
Subject: drm/i915: Only defer freeing of fence callback when also using the
 timer
Git-commit: c32164b1f6a2eafa0658bbf33d02b2da41c72e5a
Patch-mainline: v4.17-rc1
References: FATE#326289 FATE#326079 FATE#326049 FATE#322398 FATE#326166

Without an accompanying timer (for internal fences), we can free the
fence callback immediately as we do not need to employ the RCU barrier
to serialise with the timer. By avoiding the RCU delay, we can avoid the
extra mempressure under heavy inter-engine request utilisation.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180115090643.26696-1-chris@chris-wilson.co.uk

Acked-by: Petr Tesarik <ptesarik@suse.com>
---
 drivers/gpu/drm/i915/i915_sw_fence.c |   13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

--- a/drivers/gpu/drm/i915/i915_sw_fence.c
+++ b/drivers/gpu/drm/i915/i915_sw_fence.c
@@ -398,7 +398,12 @@ static void dma_i915_sw_fence_wake(struc
 	if (fence)
 		i915_sw_fence_complete(fence);
 
-	irq_work_queue(&cb->work);
+	if (cb->dma) {
+		irq_work_queue(&cb->work);
+		return;
+	}
+
+	kfree(cb);
 }
 
 static void irq_i915_sw_fence_work(struct irq_work *wrk)
@@ -437,10 +442,12 @@ int i915_sw_fence_await_dma_fence(struct
 	i915_sw_fence_await(fence);
 
 	cb->dma = NULL;
-	timer_setup(&cb->timer, timer_i915_sw_fence_wake, TIMER_IRQSAFE);
-	init_irq_work(&cb->work, irq_i915_sw_fence_work);
 	if (timeout) {
 		cb->dma = dma_fence_get(dma);
+		init_irq_work(&cb->work, irq_i915_sw_fence_work);
+
+		timer_setup(&cb->timer,
+			    timer_i915_sw_fence_wake, TIMER_IRQSAFE);
 		mod_timer(&cb->timer, round_jiffies_up(jiffies + timeout));
 	}