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@xxxxxxxxxxxxxxxxxx> Cc: Tvrtko Ursulin <tvrtko.ursulin@xxxxxxxxx> Cc: Arjun Melkaveri <arjun.melkaveri@xxxxxxxxx> --- 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 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx