lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date:   Tue, 8 Feb 2022 17:54:07 +0100
From:   Sebastian Andrzej Siewior <bigeasy@...utronix.de>
To:     linux-kernel@...r.kernel.org
Cc:     Thomas Gleixner <tglx@...utronix.de>,
        Christoph Hellwig <hch@...radead.org>,
        Peter Zijlstra <peterz@...radead.org>
Subject: [PATCH v3] smp: Wake ksoftirqd on PREEMPT_RT instead do_softirq().

The softirq implementation on PREEMPT_RT does not provide do_softirq(). The
softirq can not be handled directly here because migration_cpu_stop() is
invoked with disabled preemption/ interrupts.

A known user of scheduling softirqs from a remote function call is the block
layer. It won't happen on PREEMPT_RT because it doesn't make sense for
latency/ performance reasons and is disabled. Nevertheless this should
be handled in case of a new user pops up rather than simply ignoring it.

Waking ksoftirqd unconditionally can be problematic if softirqs were already
pending but not yet handled. This can happen since the migration thread
is running at a high priority and able to preempt a threaded-interrupt.
The woken-up ksoftirqd would catch-up all pending (and later raised)
softirqs which is not desired on PREEMPT_RT since it is no longer
handled where it has been originally raised. This in turn delays the
actual processing until a SCHED_OTHER task can run.

Wake the softirq thread on PREEMPT_RT if a remote function call raised
softirqs. Add warning in this case since this condition is not desired.

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@...utronix.de>
---
v2…v3:
   - Only wake ksoftirqd if the softirqs were raised wthin
     flush_smp_call_function_queue().
   - Add a warning in the wake case.
v1…v2: Drop an empty line.

 kernel/smp.c |   21 ++++++++++++++++++---
 1 file changed, 18 insertions(+), 3 deletions(-)
---
--- a/kernel/smp.c
+++ b/kernel/smp.c
@@ -691,10 +691,25 @@ void flush_smp_call_function_from_idle(v
 	cfd_seq_store(this_cpu_ptr(&cfd_seq_local)->idle, CFD_SEQ_NOCPU,
 		      smp_processor_id(), CFD_SEQ_IDLE);
 	local_irq_save(flags);
-	flush_smp_call_function_queue(true);
-	if (local_softirq_pending())
-		do_softirq();
+	if (!IS_ENABLED(CONFIG_PREEMPT_RT)) {
+		flush_smp_call_function_queue(true);
+		if (local_softirq_pending())
+			do_softirq();
+	} else {
+		unsigned int pending_prev;
+		unsigned int pending_post;
 
+		pending_prev = local_softirq_pending();
+		flush_smp_call_function_queue(true);
+		pending_post = local_softirq_pending();
+
+		if (WARN_ON_ONCE(!pending_prev && pending_post)) {
+			struct task_struct *ksoftirqd = this_cpu_ksoftirqd();
+
+			if (ksoftirqd && !task_is_running(ksoftirqd))
+				wake_up_process(ksoftirqd);
+		}
+	}
 	local_irq_restore(flags);
 }
 

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ