[Intel-gfx] [PATCH v2] drm/i915: Expose an option to flush the tasklets via debugfs

Chris Wilson chris at chris-wilson.co.uk
Fri Apr 17 12:49:19 UTC 2020


In some IGT we have quite strict timing requirements that are trying to
measure workloads and not the latency of execution. For these, ksoftirqd
can cause quite a bit of mischief with long and unpredictable scheduling
delays, so lets explicitly flush the softirq tasklets via the
local_bh_enable() trick. This has to be done on_each_cpu() as the
tasklets when scheduled are local to a CPU.

v2: Work around the warnings around the lack of a direct means to flush
tasklets.

Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
Cc: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
Cc: Arjun Melkaveri <arjun.melkaveri at intel.com>
---
 drivers/gpu/drm/i915/i915_debugfs.c | 31 ++++++++++++++++++++++++++++-
 1 file changed, 30 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index aa35a59f1c7d..abb56406b9dc 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -1429,6 +1429,7 @@ DEFINE_SIMPLE_ATTRIBUTE(i915_perf_noa_delay_fops,
 #define DROP_RESET_ACTIVE	BIT(7)
 #define DROP_RESET_SEQNO	BIT(8)
 #define DROP_RCU	BIT(9)
+#define DROP_TASKLETS	BIT(10)
 #define DROP_ALL (DROP_UNBOUND	| \
 		  DROP_BOUND	| \
 		  DROP_RETIRE	| \
@@ -1438,7 +1439,8 @@ DEFINE_SIMPLE_ATTRIBUTE(i915_perf_noa_delay_fops,
 		  DROP_IDLE	| \
 		  DROP_RESET_ACTIVE | \
 		  DROP_RESET_SEQNO | \
-		  DROP_RCU)
+		  DROP_RCU	| \
+		  DROP_TASKLETS)
 static int
 i915_drop_caches_get(void *data, u64 *val)
 {
@@ -1476,6 +1478,30 @@ gt_drop_caches(struct intel_gt *gt, u64 val)
 	return 0;
 }
 
+static void kick_softirq_tasklets(void *arg)
+{
+	int hardirq = in_irq();
+
+	/* Lies, lies, and damn lies */
+	preempt_count_inc();
+	preempt_count_sub(hardirq);
+
+	/* Execute the softirq tasklets immediately */
+	local_bh_disable();
+	_local_bh_enable();
+
+	/* Some tasklets may have queued others, so double check */
+	local_bh_disable();
+	_local_bh_enable();
+
+	/* Third time's the charm. I don't think we recurse any deeper! */
+	local_bh_disable();
+	_local_bh_enable();
+
+	preempt_count_add(hardirq);
+	preempt_count_dec();
+}
+
 static int
 i915_drop_caches_set(void *data, u64 val)
 {
@@ -1485,6 +1511,9 @@ i915_drop_caches_set(void *data, u64 val)
 	DRM_DEBUG("Dropping caches: 0x%08llx [0x%08llx]\n",
 		  val, val & DROP_ALL);
 
+	if (val & DROP_TASKLETS)
+		on_each_cpu(kick_softirq_tasklets, NULL, true);
+
 	ret = gt_drop_caches(&i915->gt, val);
 	if (ret)
 		return ret;
-- 
2.20.1



More information about the Intel-gfx mailing list