mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: "tip-bot2 for Anna-Maria Behnsen" <tip-bot2@linutronix.de>
To: linux-tip-commits@vger.kernel.org
Cc: "Anna-Maria Behnsen" <anna-maria@linutronix.de>,
	Thomas Gleixner <tglx@linutronix.de>,
	Frederic Weisbecker <frederic@kernel.org>,
	x86@kernel.org, linux-kernel@vger.kernel.org
Subject: [tip: timers/core] timers: Add get next timer interrupt functionality for remote CPUs
Date: Thu, 22 Feb 2024 17:12:09 -0000	[thread overview]
Message-ID: <170862192926.398.11570971415900571858.tip-bot2@tip-bot2> (raw)
In-Reply-To: <20240221090548.36600-14-anna-maria@linutronix.de>

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

Commit-ID:     f73d9257ff3c2f415e8c342a91b7f5acfc3ce512
Gitweb:        https://git.kernel.org/tip/f73d9257ff3c2f415e8c342a91b7f5acfc3ce512
Author:        Anna-Maria Behnsen <anna-maria@linutronix.de>
AuthorDate:    Wed, 21 Feb 2024 10:05:41 +01:00
Committer:     Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Thu, 22 Feb 2024 17:52:31 +01:00

timers: Add get next timer interrupt functionality for remote CPUs

To prepare for the conversion of the NOHZ timer placement to a pull at
expiry time model it's required to have functionality available getting the
next timer interrupt on a remote CPU.

Locking of the timer bases and getting the information for the next timer
interrupt functionality is split into separate functions. This is required
to be compliant with lock ordering when the new model is in place.

Signed-off-by: Anna-Maria Behnsen <anna-maria@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Frederic Weisbecker <frederic@kernel.org>
Link: https://lore.kernel.org/r/20240221090548.36600-14-anna-maria@linutronix.de

---
 kernel/time/tick-internal.h | 10 ++++-
 kernel/time/timer.c         | 95 ++++++++++++++++++++++++++++++++++--
 2 files changed, 100 insertions(+), 5 deletions(-)

diff --git a/kernel/time/tick-internal.h b/kernel/time/tick-internal.h
index 47df30b..8b0c28e 100644
--- a/kernel/time/tick-internal.h
+++ b/kernel/time/tick-internal.h
@@ -8,6 +8,11 @@
 #include "timekeeping.h"
 #include "tick-sched.h"
 
+struct timer_events {
+	u64	local;
+	u64	global;
+};
+
 #ifdef CONFIG_GENERIC_CLOCKEVENTS
 
 # define TICK_DO_TIMER_NONE	-1
@@ -154,6 +159,11 @@ extern unsigned long tick_nohz_active;
 extern void timers_update_nohz(void);
 # ifdef CONFIG_SMP
 extern struct static_key_false timers_migration_enabled;
+extern void fetch_next_timer_interrupt_remote(unsigned long basej, u64 basem,
+					      struct timer_events *tevt,
+					      unsigned int cpu);
+extern void timer_lock_remote_bases(unsigned int cpu);
+extern void timer_unlock_remote_bases(unsigned int cpu);
 # endif
 #else /* CONFIG_NO_HZ_COMMON */
 static inline void timers_update_nohz(void) { }
diff --git a/kernel/time/timer.c b/kernel/time/timer.c
index b10e97c..bc074c0 100644
--- a/kernel/time/timer.c
+++ b/kernel/time/timer.c
@@ -266,11 +266,6 @@ struct timer_base {
 
 static DEFINE_PER_CPU(struct timer_base, timer_bases[NR_BASES]);
 
-struct timer_events {
-	u64	local;
-	u64	global;
-};
-
 #ifdef CONFIG_NO_HZ_COMMON
 
 static DEFINE_STATIC_KEY_FALSE(timers_nohz_active);
@@ -2058,6 +2053,21 @@ static unsigned long fetch_next_timer_interrupt(unsigned long basej, u64 basem,
 		if (time_before(nextevt, basej))
 			nextevt = basej;
 		tevt->local = basem + (u64)(nextevt - basej) * TICK_NSEC;
+
+		/*
+		 * This is required for the remote check only but it doesn't
+		 * hurt, when it is done for both call sites:
+		 *
+		 * * The remote callers will only take care of the global timers
+		 *   as local timers will be handled by CPU itself. When not
+		 *   updating tevt->global with the already missed first global
+		 *   timer, it is possible that it will be missed completely.
+		 *
+		 * * The local callers will ignore the tevt->global anyway, when
+		 *   nextevt is max. one tick away.
+		 */
+		if (!local_first)
+			tevt->global = tevt->local;
 		return nextevt;
 	}
 
@@ -2076,6 +2086,81 @@ static unsigned long fetch_next_timer_interrupt(unsigned long basej, u64 basem,
 	return nextevt;
 }
 
+# ifdef CONFIG_SMP
+/**
+ * fetch_next_timer_interrupt_remote() - Store next timers into @tevt
+ * @basej:	base time jiffies
+ * @basem:	base time clock monotonic
+ * @tevt:	Pointer to the storage for the expiry values
+ * @cpu:	Remote CPU
+ *
+ * Stores the next pending local and global timer expiry values in the
+ * struct pointed to by @tevt. If a queue is empty the corresponding
+ * field is set to KTIME_MAX. If local event expires before global
+ * event, global event is set to KTIME_MAX as well.
+ *
+ * Caller needs to make sure timer base locks are held (use
+ * timer_lock_remote_bases() for this purpose).
+ */
+void fetch_next_timer_interrupt_remote(unsigned long basej, u64 basem,
+				       struct timer_events *tevt,
+				       unsigned int cpu)
+{
+	struct timer_base *base_local, *base_global;
+
+	/* Preset local / global events */
+	tevt->local = tevt->global = KTIME_MAX;
+
+	base_local = per_cpu_ptr(&timer_bases[BASE_LOCAL], cpu);
+	base_global = per_cpu_ptr(&timer_bases[BASE_GLOBAL], cpu);
+
+	lockdep_assert_held(&base_local->lock);
+	lockdep_assert_held(&base_global->lock);
+
+	fetch_next_timer_interrupt(basej, basem, base_local, base_global, tevt);
+}
+
+/**
+ * timer_unlock_remote_bases - unlock timer bases of cpu
+ * @cpu:	Remote CPU
+ *
+ * Unlocks the remote timer bases.
+ */
+void timer_unlock_remote_bases(unsigned int cpu)
+	__releases(timer_bases[BASE_LOCAL]->lock)
+	__releases(timer_bases[BASE_GLOBAL]->lock)
+{
+	struct timer_base *base_local, *base_global;
+
+	base_local = per_cpu_ptr(&timer_bases[BASE_LOCAL], cpu);
+	base_global = per_cpu_ptr(&timer_bases[BASE_GLOBAL], cpu);
+
+	raw_spin_unlock(&base_global->lock);
+	raw_spin_unlock(&base_local->lock);
+}
+
+/**
+ * timer_lock_remote_bases - lock timer bases of cpu
+ * @cpu:	Remote CPU
+ *
+ * Locks the remote timer bases.
+ */
+void timer_lock_remote_bases(unsigned int cpu)
+	__acquires(timer_bases[BASE_LOCAL]->lock)
+	__acquires(timer_bases[BASE_GLOBAL]->lock)
+{
+	struct timer_base *base_local, *base_global;
+
+	base_local = per_cpu_ptr(&timer_bases[BASE_LOCAL], cpu);
+	base_global = per_cpu_ptr(&timer_bases[BASE_GLOBAL], cpu);
+
+	lockdep_assert_irqs_disabled();
+
+	raw_spin_lock(&base_local->lock);
+	raw_spin_lock_nested(&base_global->lock, SINGLE_DEPTH_NESTING);
+}
+# endif /* CONFIG_SMP */
+
 static inline u64 __get_next_timer_interrupt(unsigned long basej, u64 basem,
 					     bool *idle)
 {

  parent reply	other threads:[~2024-02-22 17:12 UTC|newest]

Thread overview: 56+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-02-21  9:05 [PATCH v11 00/20] timers: Move from a push remote at enqueue to a pull at expiry model Anna-Maria Behnsen
2024-02-21  9:05 ` [PATCH v11 01/20] timers: Restructure get_next_timer_interrupt() Anna-Maria Behnsen
2024-02-22 17:12   ` [tip: timers/core] " tip-bot2 for Anna-Maria Behnsen
2024-02-21  9:05 ` [PATCH v11 02/20] timers: Split out get next timer interrupt Anna-Maria Behnsen
2024-02-22 17:12   ` [tip: timers/core] " tip-bot2 for Anna-Maria Behnsen
2024-02-21  9:05 ` [PATCH v11 03/20] timers: Move marking timer bases idle into tick_nohz_stop_tick() Anna-Maria Behnsen
2024-02-21 20:36   ` Frederic Weisbecker
2024-02-22 17:12   ` [tip: timers/core] " tip-bot2 for Anna-Maria Behnsen
2024-02-21  9:05 ` [PATCH v11 04/20] timers: Optimization for timer_base_try_to_set_idle() Anna-Maria Behnsen
2024-02-22 17:12   ` [tip: timers/core] " tip-bot2 for Anna-Maria Behnsen
2024-02-21  9:05 ` [PATCH v11 05/20] timers: Introduce add_timer() variants which modify timer flags Anna-Maria Behnsen
2024-02-22 17:12   ` [tip: timers/core] " tip-bot2 for Anna-Maria Behnsen
2024-02-21  9:05 ` [PATCH v11 06/20] workqueue: Use global variant for add_timer() Anna-Maria Behnsen
2024-02-22 17:12   ` [tip: timers/core] " tip-bot2 for Anna-Maria Behnsen
2024-02-21  9:05 ` [PATCH v11 07/20] timers: add_timer_on(): Make sure TIMER_PINNED flag is set Anna-Maria Behnsen
2024-02-22 17:12   ` [tip: timers/core] timers: Make sure TIMER_PINNED flag is set in add_timer_on() tip-bot2 for Anna-Maria Behnsen
2024-02-21  9:05 ` [PATCH v11 08/20] timers: Ease code in run_local_timers() Anna-Maria Behnsen
2024-02-22 17:12   ` [tip: timers/core] timers: Simplify " tip-bot2 for Anna-Maria Behnsen
2024-02-21  9:05 ` [PATCH v11 09/20] timers: Split next timer interrupt logic Anna-Maria Behnsen
2024-02-22 17:12   ` [tip: timers/core] " tip-bot2 for Anna-Maria Behnsen
2024-02-21  9:05 ` [PATCH v11 10/20] timers: Keep the pinned timers separate from the others Anna-Maria Behnsen
2024-02-22 17:12   ` [tip: timers/core] " tip-bot2 for Anna-Maria Behnsen
2024-02-21  9:05 ` [PATCH v11 11/20] timers: Retrieve next expiry of pinned/non-pinned timers separately Anna-Maria Behnsen
2024-02-22 17:12   ` [tip: timers/core] " tip-bot2 for Anna-Maria Behnsen
2024-02-21  9:05 ` [PATCH v11 12/20] timers: Split out "get next timer interrupt" functionality Anna-Maria Behnsen
2024-02-22 17:12   ` [tip: timers/core] " tip-bot2 for Anna-Maria Behnsen
2024-02-21  9:05 ` [PATCH v11 13/20] timers: Add get next timer interrupt functionality for remote CPUs Anna-Maria Behnsen
2024-02-21 20:50   ` Frederic Weisbecker
2024-02-22 17:12   ` tip-bot2 for Anna-Maria Behnsen [this message]
2024-02-21  9:05 ` [PATCH v11 14/20] timers: Restructure internal locking Anna-Maria Behnsen
2024-02-22 17:12   ` [tip: timers/core] " tip-bot2 for Richard Cochran (linutronix GmbH)
2024-02-21  9:05 ` [PATCH v11 15/20] timers: Check if timers base is handled already Anna-Maria Behnsen
2024-02-22 17:12   ` [tip: timers/core] " tip-bot2 for Anna-Maria Behnsen
2024-02-21  9:05 ` [PATCH v11 16/20] tick/sched: Split out jiffies update helper function Anna-Maria Behnsen
2024-02-22 17:12   ` [tip: timers/core] " tip-bot2 for Richard Cochran (linutronix GmbH)
2024-02-21  9:05 ` [PATCH v11 17/20] timers: Introduce function to check timer base is_idle flag Anna-Maria Behnsen
2024-02-22 17:12   ` [tip: timers/core] " tip-bot2 for Anna-Maria Behnsen
2024-02-21  9:05 ` [PATCH v11 18/20] timers: Implement the hierarchical pull model Anna-Maria Behnsen
2024-02-21 10:37   ` [PATCH v11a] " Anna-Maria Behnsen
2024-02-21 22:45   ` [PATCH v11 18/20] " Frederic Weisbecker
2024-02-22  8:17     ` Anna-Maria Behnsen
2024-02-22 10:25       ` Frederic Weisbecker
2024-02-22 10:37   ` [PATCH v11b " Anna-Maria Behnsen
2024-02-22 10:50     ` Frederic Weisbecker
2024-02-22 17:12     ` [tip: timers/core] " tip-bot2 for Anna-Maria Behnsen
2024-02-21  9:05 ` [PATCH v11 19/20] timer_migration: Add tracepoints Anna-Maria Behnsen
2024-02-21 22:46   ` Frederic Weisbecker
2024-02-21 23:17   ` Steven Rostedt
2024-02-22 10:34   ` [PATCH v11a " Anna-Maria Behnsen
2024-02-22 14:59     ` Steven Rostedt
2024-02-22 17:12     ` [tip: timers/core] " tip-bot2 for Anna-Maria Behnsen
2024-02-21  9:05 ` [PATCH v11 20/20] timers: Always queue timers on the local CPU Anna-Maria Behnsen
2024-02-21 22:57   ` Frederic Weisbecker
2024-02-22 17:12   ` [tip: timers/core] " tip-bot2 for Anna-Maria Behnsen
2024-02-22 13:33 ` [PATCH] timers/timer_migration: Fix memory barrier comment Anna-Maria Behnsen
2024-02-22 13:44   ` Frederic Weisbecker

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=170862192926.398.11570971415900571858.tip-bot2@tip-bot2 \
    --to=tip-bot2@linutronix.de \
    --cc=anna-maria@linutronix.de \
    --cc=frederic@kernel.org \
    --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®