[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20240624-tmigr-fixes-v2-3-3eb4c0604790@linutronix.de>
Date: Mon, 24 Jun 2024 16:53:55 +0200
From: Anna-Maria Behnsen <anna-maria@...utronix.de>
To: Frederic Weisbecker <frederic@...nel.org>,
Thomas Gleixner <tglx@...utronix.de>, linux-kernel@...r.kernel.org
Cc: Anna-Maria Behnsen <anna-maria@...utronix.de>
Subject: [PATCH v2 3/5] timer_migration: Split out state update of
tmigr_active_up()
The functionality of the state update is split into __tmigr_active_up() to
be reusable by other callsites.
This is a preparation for a fix of a potential race when a CPU comes online
the first time and creates a new top level.
No functional change.
Fixes: 7ee988770326 ("timers: Implement the hierarchical pull model")
Signed-off-by: Anna-Maria Behnsen <anna-maria@...utronix.de>
---
kernel/time/timer_migration.c | 47 ++++++++++++++++++++++++++-----------------
1 file changed, 29 insertions(+), 18 deletions(-)
diff --git a/kernel/time/timer_migration.c b/kernel/time/timer_migration.c
index 600c9e866fae..0e1c53dac390 100644
--- a/kernel/time/timer_migration.c
+++ b/kernel/time/timer_migration.c
@@ -623,12 +623,38 @@ static u64 tmigr_next_groupevt_expires(struct tmigr_group *group)
return evt->nextevt.expires;
}
+static bool __tmigr_active_up(struct tmigr_group *group, bool *walk_done,
+ union tmigr_state *curstate, u8 childmask)
+{
+ union tmigr_state newstate;
+
+ newstate = *curstate;
+ *walk_done = true;
+
+ if (newstate.migrator == TMIGR_NONE) {
+ newstate.migrator = childmask;
+
+ /* Changes need to be propagated */
+ *walk_done = false;
+ }
+
+ newstate.active |= childmask;
+ newstate.seq++;
+
+ if (atomic_try_cmpxchg(&group->migr_state, &curstate->state, newstate.state)) {
+ trace_tmigr_group_set_cpu_active(group, newstate, childmask);
+ return true;
+ }
+
+ return false;
+}
+
static bool tmigr_active_up(struct tmigr_group *group,
struct tmigr_group *child,
void *ptr)
{
- union tmigr_state curstate, newstate;
struct tmigr_walk *data = ptr;
+ union tmigr_state curstate;
bool walk_done;
u8 childmask;
@@ -640,23 +666,8 @@ static bool tmigr_active_up(struct tmigr_group *group,
*/
curstate.state = atomic_read(&group->migr_state);
- do {
- newstate = curstate;
- walk_done = true;
-
- if (newstate.migrator == TMIGR_NONE) {
- newstate.migrator = childmask;
-
- /* Changes need to be propagated */
- walk_done = false;
- }
-
- newstate.active |= childmask;
- newstate.seq++;
-
- } while (!atomic_try_cmpxchg(&group->migr_state, &curstate.state, newstate.state));
-
- trace_tmigr_group_set_cpu_active(group, newstate, childmask);
+ while (!__tmigr_active_up(group, &walk_done, &curstate, childmask))
+ ;
if (walk_done == false)
data->childmask = group->childmask;
--
2.39.2
Powered by blists - more mailing lists