[PATCH v2 3/5] timer_migration: Split out state update of tmigr_active_up()

Anna-Maria Behnsen posted 5 patches 1 year, 5 months ago
[PATCH v2 3/5] timer_migration: Split out state update of tmigr_active_up()
Posted by Anna-Maria Behnsen 1 year, 5 months ago
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@linutronix.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
Re: [PATCH v2 3/5] timer_migration: Split out state update of tmigr_active_up()
Posted by Frederic Weisbecker 1 year, 5 months ago
Le Mon, Jun 24, 2024 at 04:53:55PM +0200, Anna-Maria Behnsen a écrit :
> 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@linutronix.de>

Reviewed-by: Frederic Weisbecker <frederic@kernel.org>