public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Frederic Weisbecker <frederic@kernel.org>
To: LKML <linux-kernel@vger.kernel.org>
Cc: Frederic Weisbecker <frederic@kernel.org>,
	Sebastian Andrzej Siewior <bigeasy@linutronix.de>,
	Peter Zijlstra <peterz@infradead.org>,
	Thomas Gleixner <tglx@linutronix.de>,
	"Paul E . McKenney" <paulmck@kernel.org>,
	Linus Torvalds <torvalds@linux-foundation.org>,
	Anna-Maria Behnsen <anna-maria@linutronix.de>,
	Eric Dumazet <edumazet@google.com>
Subject: [RFC PATCH 3/6] softirq: Introduce softirq disabled mask
Date: Tue,  1 Aug 2023 15:24:38 +0200	[thread overview]
Message-ID: <20230801132441.559222-4-frederic@kernel.org> (raw)
In-Reply-To: <20230801132441.559222-1-frederic@kernel.org>

(DISCLAIMER: contains -RT bits)

When softirq vectors will be able to re-enable softirqs when deemed
safe, for example when a timer callback is tagged as soft-interruptible
by other softirq vectors, care must be taken to ensure a given vector
is not re-entrant. Ie: a vector can be interrupted by others but not
by itself.

In order to prepare for this, introduce a softirq disabled mask so that
vectors can disable themselves before re-enabling softirqs.

Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
---
 arch/Kconfig                |  3 +++
 include/linux/bottom_half.h |  2 ++
 include/linux/interrupt.h   | 15 ++++++++++++---
 kernel/softirq.c            | 16 +++++++++++++++-
 4 files changed, 32 insertions(+), 4 deletions(-)

diff --git a/arch/Kconfig b/arch/Kconfig
index 205fd23e0cad..d23968860ddf 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -1358,6 +1358,9 @@ config RELR
 config ARCH_HAS_MEM_ENCRYPT
 	bool
 
+config ARCH_HAS_SOFTIRQ_DISABLED_MASK
+       bool
+
 config ARCH_HAS_CC_PLATFORM
 	bool
 
diff --git a/include/linux/bottom_half.h b/include/linux/bottom_half.h
index 2243c7de4917..d5b37b580c79 100644
--- a/include/linux/bottom_half.h
+++ b/include/linux/bottom_half.h
@@ -42,6 +42,8 @@ extern void local_bh_exit(void);
 
 #ifdef CONFIG_PREEMPT_RT
 extern bool local_bh_blocked(void);
+extern void local_bh_vec_enable(int vec);
+extern void local_bh_vec_disable(int vec);
 #else
 static inline bool local_bh_blocked(void) { return false; }
 #endif
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index 2099fe3980bc..7819d16d8d6f 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -523,8 +523,16 @@ DECLARE_STATIC_KEY_FALSE(force_irqthreads_key);
 #define local_softirq_pending_ref irq_stat.__softirq_pending
 #endif
 
-#define local_softirq_pending()	(__this_cpu_read(local_softirq_pending_ref))
-#define reset_softirq_pending()	(__this_cpu_write(local_softirq_pending_ref, 0))
+#if defined(CONFIG_PREEMPT_RT) && defined(CONFIG_ARCH_HAS_SOFTIRQ_DISABLED_MASK)
+#define local_softirq_disabled()	(__this_cpu_read(local_softirq_disabled_ref))
+#else
+#define local_softirq_disabled()	(0)
+#endif
+
+#define local_softirq_pending()	(__this_cpu_read(local_softirq_pending_ref) & \
+				 ~local_softirq_disabled())
+#define reset_softirq_pending() (__this_cpu_and(local_softirq_pending_ref, \
+				local_softirq_disabled()))
 #define or_softirq_pending(x)	(__this_cpu_or(local_softirq_pending_ref, (x)))
 
 #endif /* local_softirq_pending */
@@ -614,7 +622,8 @@ extern void raise_hrtimer_softirq(void);
 
 static inline unsigned int local_pending_timers(void)
 {
-        return __this_cpu_read(pending_timer_softirq);
+        return __this_cpu_read(pending_timer_softirq) &
+		~local_softirq_disabled();
 }
 
 #else
diff --git a/kernel/softirq.c b/kernel/softirq.c
index ba998d572ef4..a394f78de627 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -297,6 +297,18 @@ void do_softirq_post_smp_call_flush(unsigned int was_pending)
 		invoke_softirq();
 }
 
+#ifdef CONFIG_ARCH_HAS_SOFTIRQ_DISABLED_MASK
+void local_bh_vec_enable(int vec)
+{
+	__this_cpu_and(local_softirq_disabled_ref, ~vec);
+}
+
+void local_bh_vec_disable(int vec)
+{
+	__this_cpu_or(local_softirq_disabled_ref, vec);
+}
+#endif
+
 #else /* CONFIG_PREEMPT_RT */
 
 /*
@@ -1009,11 +1021,13 @@ static int timersd_should_run(unsigned int cpu)
 static void run_timersd(unsigned int cpu)
 {
 	unsigned int timer_si;
+	unsigned long timersd_vecs = (1 << TIMER_SOFTIRQ) | (1 << HRTIMER_SOFTIRQ);
 
 	ksoftirqd_run_begin();
 
 	timer_si = local_pending_timers();
-	__this_cpu_write(pending_timer_softirq, 0);
+	__this_cpu_and(pending_timer_softirq,
+		       local_softirq_disabled() & timersd_vecs);
 	or_softirq_pending(timer_si);
 
 	__do_softirq();
-- 
2.34.1


  parent reply	other threads:[~2023-08-01 13:25 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-08-01 13:24 [RFC PATCH 0/6] softirq: Start pushing down the big softirq lock Frederic Weisbecker
2023-08-01 13:24 ` [RFC PATCH 1/6] softirq: Turn set_softirq_pending() to reset_softirq_pending() Frederic Weisbecker
2023-08-01 13:24 ` [RFC PATCH 2/6] softirq: Make softirq handling entry/exit generally available Frederic Weisbecker
2023-08-01 13:24 ` Frederic Weisbecker [this message]
2023-08-01 13:24 ` [RFC PATCH 4/6] x86/softirq: Support softirq disabled mask Frederic Weisbecker
2023-08-01 13:24 ` [RFC PATCH 5/6] timers: Introduce soft-interruptible timers Frederic Weisbecker
2023-08-01 13:24 ` [RFC PATCH 6/6] timers: Make process_timeout() soft-interruptible Frederic Weisbecker
2023-08-07 12:50 ` [RFC PATCH 0/6] softirq: Start pushing down the big softirq lock Sebastian Andrzej Siewior
2023-08-07 15:22   ` Frederic Weisbecker
2023-08-08  7:15     ` Sebastian Andrzej Siewior

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230801132441.559222-4-frederic@kernel.org \
    --to=frederic@kernel.org \
    --cc=anna-maria@linutronix.de \
    --cc=bigeasy@linutronix.de \
    --cc=edumazet@google.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=paulmck@kernel.org \
    --cc=peterz@infradead.org \
    --cc=tglx@linutronix.de \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox