mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: "tip-bot2 for Thomas Gleixner" <tip-bot2@linutronix.de>
To: linux-tip-commits@vger.kernel.org
Cc: Borislav Petkov <bp@alien8.de>,
	Thomas Gleixner <tglx@linutronix.de>,
	x86@kernel.org, linux-kernel@vger.kernel.org
Subject: [tip: x86/core] sched/idle: Conditionally handle tick broadcast in default_idle_call()
Date: Fri, 01 Mar 2024 20:48:44 -0000	[thread overview]
Message-ID: <170932612462.398.15833470158375898227.tip-bot2@tip-bot2> (raw)
In-Reply-To: <20240229142248.266708822@linutronix.de>

The following commit has been merged into the x86/core branch of tip:

Commit-ID:     2be2a197ff6c3a659ab9285e1d88cbdc609ac6de
Gitweb:        https://git.kernel.org/tip/2be2a197ff6c3a659ab9285e1d88cbdc609ac6de
Author:        Thomas Gleixner <tglx@linutronix.de>
AuthorDate:    Thu, 29 Feb 2024 15:23:36 +01:00
Committer:     Borislav Petkov (AMD) <bp@alien8.de>
CommitterDate: Fri, 01 Mar 2024 21:04:27 +01:00

sched/idle: Conditionally handle tick broadcast in default_idle_call()

The x86 architecture has an idle routine for AMD CPUs which are affected
by erratum 400. On the affected CPUs the local APIC timer stops in the
C1E halt state.

It therefore requires tick broadcasting. The invocation of
tick_broadcast_enter()/exit() from this function violates the RCU
constraints because it can end up in lockdep or tracing, which
rightfully triggers a warning.

tick_broadcast_enter()/exit() must be invoked before ct_cpuidle_enter()
and after ct_cpuidle_exit() in default_idle_call().

Add a static branch conditional invocation of tick_broadcast_enter()/exit()
into this function to allow X86 to replace the AMD specific idle code. It's
guarded by a config switch which will be selected by x86. Otherwise it's
a NOOP.

Reported-by: Borislav Petkov <bp@alien8.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Link: https://lore.kernel.org/r/20240229142248.266708822@linutronix.de
---
 include/linux/cpu.h  |  2 ++
 include/linux/tick.h |  3 +++
 kernel/sched/idle.c  | 21 +++++++++++++++++++++
 kernel/time/Kconfig  |  5 +++++
 4 files changed, 31 insertions(+)

diff --git a/include/linux/cpu.h b/include/linux/cpu.h
index dcb89c9..715017d 100644
--- a/include/linux/cpu.h
+++ b/include/linux/cpu.h
@@ -196,6 +196,8 @@ void arch_cpu_idle(void);
 void arch_cpu_idle_prepare(void);
 void arch_cpu_idle_enter(void);
 void arch_cpu_idle_exit(void);
+void arch_tick_broadcast_enter(void);
+void arch_tick_broadcast_exit(void);
 void __noreturn arch_cpu_idle_dead(void);
 
 #ifdef CONFIG_ARCH_HAS_CPU_FINALIZE_INIT
diff --git a/include/linux/tick.h b/include/linux/tick.h
index 716d17f..e134f28 100644
--- a/include/linux/tick.h
+++ b/include/linux/tick.h
@@ -12,6 +12,7 @@
 #include <linux/cpumask.h>
 #include <linux/sched.h>
 #include <linux/rcupdate.h>
+#include <linux/static_key.h>
 
 #ifdef CONFIG_GENERIC_CLOCKEVENTS
 extern void __init tick_init(void);
@@ -63,6 +64,8 @@ enum tick_broadcast_state {
 	TICK_BROADCAST_ENTER,
 };
 
+extern struct static_key_false arch_needs_tick_broadcast;
+
 #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
 extern void tick_broadcast_control(enum tick_broadcast_mode mode);
 #else
diff --git a/kernel/sched/idle.c b/kernel/sched/idle.c
index 3123192..31ad811 100644
--- a/kernel/sched/idle.c
+++ b/kernel/sched/idle.c
@@ -81,6 +81,25 @@ void __weak arch_cpu_idle(void)
 	cpu_idle_force_poll = 1;
 }
 
+#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST_IDLE
+DEFINE_STATIC_KEY_FALSE(arch_needs_tick_broadcast);
+
+static inline void cond_tick_broadcast_enter(void)
+{
+	if (static_branch_unlikely(&arch_needs_tick_broadcast))
+		tick_broadcast_enter();
+}
+
+static inline void cond_tick_broadcast_exit(void)
+{
+	if (static_branch_unlikely(&arch_needs_tick_broadcast))
+		tick_broadcast_exit();
+}
+#else
+static inline void cond_tick_broadcast_enter(void) { }
+static inline void cond_tick_broadcast_exit(void) { }
+#endif
+
 /**
  * default_idle_call - Default CPU idle routine.
  *
@@ -90,6 +109,7 @@ void __cpuidle default_idle_call(void)
 {
 	instrumentation_begin();
 	if (!current_clr_polling_and_test()) {
+		cond_tick_broadcast_enter();
 		trace_cpu_idle(1, smp_processor_id());
 		stop_critical_timings();
 
@@ -99,6 +119,7 @@ void __cpuidle default_idle_call(void)
 
 		start_critical_timings();
 		trace_cpu_idle(PWR_EVENT_EXIT, smp_processor_id());
+		cond_tick_broadcast_exit();
 	}
 	local_irq_enable();
 	instrumentation_end();
diff --git a/kernel/time/Kconfig b/kernel/time/Kconfig
index bae8f11..fc3b1a0 100644
--- a/kernel/time/Kconfig
+++ b/kernel/time/Kconfig
@@ -39,6 +39,11 @@ config GENERIC_CLOCKEVENTS_BROADCAST
 	bool
 	depends on GENERIC_CLOCKEVENTS
 
+# Handle broadcast in default_idle_call()
+config GENERIC_CLOCKEVENTS_BROADCAST_IDLE
+	bool
+	depends on GENERIC_CLOCKEVENTS_BROADCAST
+
 # Automatically adjust the min. reprogramming time for
 # clock event device
 config GENERIC_CLOCKEVENTS_MIN_ADJUST

  reply	other threads:[~2024-03-01 20:48 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-02-29 14:23 [patch 0/6] x86/idle: Cure RCU violations and cleanups Thomas Gleixner
2024-02-29 14:23 ` [patch 1/6] sched/idle: Conditionally handle tick broadcast in default_idle_call() Thomas Gleixner
2024-03-01 20:48   ` tip-bot2 for Thomas Gleixner [this message]
2024-02-29 14:23 ` [patch 2/6] x86/idle: Sanitize X86_BUG_AMD_E400 handling Thomas Gleixner
2024-03-01 12:33   ` Thomas Gleixner
2024-03-01 20:48     ` [tip: x86/core] " tip-bot2 for Thomas Gleixner
2024-03-04 16:51     ` tip-bot2 for Thomas Gleixner
2024-02-29 14:23 ` [patch 3/6] x86/idle: Clean up idle selection Thomas Gleixner
2024-03-01 20:48   ` [tip: x86/core] " tip-bot2 for Thomas Gleixner
2024-03-04 16:51   ` tip-bot2 for Thomas Gleixner
2024-02-29 14:23 ` [patch 4/6] x86/idle: Cleanup idle_setup() Thomas Gleixner
2024-03-01 20:48   ` [tip: x86/core] " tip-bot2 for Thomas Gleixner
2024-03-04 16:51   ` tip-bot2 for Thomas Gleixner
2024-02-29 14:23 ` [patch 5/6] x86/idle: Let prefer_mwait_c1_over_halt() return bool Thomas Gleixner
2024-03-01 20:48   ` [tip: x86/core] " tip-bot2 for Thomas Gleixner
2024-03-04 16:51   ` tip-bot2 for Thomas Gleixner
2024-02-29 14:23 ` [patch 6/6] x86/idle: Select idle routine only once Thomas Gleixner
2024-03-01  8:14   ` Thomas Gleixner
2024-03-01 11:33     ` Thomas Gleixner
2024-03-01 20:48       ` [tip: x86/core] " tip-bot2 for Thomas Gleixner
2024-03-04 16:51       ` tip-bot2 for Thomas Gleixner
2024-03-01 18:41 ` [patch 0/6] x86/idle: Cure RCU violations and cleanups Borislav Petkov

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=170932612462.398.15833470158375898227.tip-bot2@tip-bot2 \
    --to=tip-bot2@linutronix.de \
    --cc=bp@alien8.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-tip-commits@vger.kernel.org \
    --cc=tglx@linutronix.de \
    --cc=x86@kernel.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

all inboxes | Powered by JetHome®