[PATCH 70/76] softirq: Prefer low-latency over ksoftirqd for HI_SOFTIRQ

Chris Wilson chris at chris-wilson.co.uk
Wed Jan 24 21:41:45 UTC 2018


References: 4cd13c21b207 ("softirq: Let ksoftirqd do its job")
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
---
 kernel/softirq.c | 26 +++++++++++++++++---------
 1 file changed, 17 insertions(+), 9 deletions(-)

diff --git a/kernel/softirq.c b/kernel/softirq.c
index 2f5e87f1bae2..1be9ace013ec 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -81,11 +81,15 @@ static void wakeup_softirqd(void)
  * If ksoftirqd is scheduled, we do not want to process pending softirqs
  * right now. Let ksoftirqd handle this at its own rate, to get fairness.
  */
-static bool ksoftirqd_running(void)
+static bool ksoftirqd_running(__u32 pending)
 {
-	struct task_struct *tsk = __this_cpu_read(ksoftirqd);
+	struct task_struct *tsk;
+
+	if (pending & HI_SOFTIRQ)
+		return false;
 
-	return tsk && (tsk->state == TASK_RUNNING);
+	tsk = __this_cpu_read(ksoftirqd);
+	return tsk && !(tsk->state & TASK_NORMAL);
 }
 
 /*
@@ -299,7 +303,8 @@ asmlinkage __visible void __softirq_entry __do_softirq(void)
 
 	pending = local_softirq_pending();
 	if (pending) {
-		if (time_before(jiffies, end) && !need_resched() &&
+		if (!ksoftirqd_running(pending) &&
+		    time_before(jiffies, end) && !need_resched() &&
 		    --max_restart)
 			goto restart;
 
@@ -325,7 +330,7 @@ asmlinkage __visible void do_softirq(void)
 
 	pending = local_softirq_pending();
 
-	if (pending && !ksoftirqd_running())
+	if (pending && !ksoftirqd_running(pending))
 		do_softirq_own_stack();
 
 	local_irq_restore(flags);
@@ -350,12 +355,15 @@ void irq_enter(void)
 	__irq_enter();
 }
 
-static inline void invoke_softirq(void)
+static inline void invoke_softirq(__u32 pending)
 {
-	if (ksoftirqd_running())
+	if (!pending)
 		return;
 
 	if (!force_irqthreads) {
+		if (ksoftirqd_running(pending))
+			return;
+
 #ifdef CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK
 		/*
 		 * We can safely execute softirq on the current stack if
@@ -401,8 +409,8 @@ void irq_exit(void)
 #endif
 	account_irq_exit_time(current);
 	preempt_count_sub(HARDIRQ_OFFSET);
-	if (!in_interrupt() && local_softirq_pending())
-		invoke_softirq();
+	if (!in_interrupt())
+		invoke_softirq(local_softirq_pending());
 
 	tick_irq_exit();
 	rcu_irq_exit();
-- 
2.15.1



More information about the Intel-gfx-trybot mailing list