summaryrefslogtreecommitdiff
path: root/kernel/time/timer_migration.c
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2026-06-03 17:00:06 +0200
committerPaolo Bonzini <pbonzini@redhat.com>2026-06-03 17:00:06 +0200
commit9fb628b4cd3488a36e3fc9b22bb840048aa1a9d2 (patch)
tree393daf8614f7915c98eca753d79545aa7e9feb99 /kernel/time/timer_migration.c
parentffb83b98357658b44a8a3b617a42d7ae48514ffd (diff)
parentc114187c5dcf1a66a2910ec66a87d230d523e5c1 (diff)
downloadlinux-next-9fb628b4cd3488a36e3fc9b22bb840048aa1a9d2.tar.gz
linux-next-9fb628b4cd3488a36e3fc9b22bb840048aa1a9d2.zip
Merge branch 'kvm-ghcb-for-7.2' into HEAD
Merge the final part of the GHCB 7.2 fixes at https://lore.kernel.org/kvm/20260529183549.1104619-1-pbonzini@redhat.com/. Patches 1-17 have already been included in Linux 7.1; these are minor cleanups, and fixes for behaviors that are suboptimal or contradicting the specification. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'kernel/time/timer_migration.c')
-rw-r--r--kernel/time/timer_migration.c40
1 files changed, 29 insertions, 11 deletions
diff --git a/kernel/time/timer_migration.c b/kernel/time/timer_migration.c
index 155eeaea4113..1d0d3a4058d5 100644
--- a/kernel/time/timer_migration.c
+++ b/kernel/time/timer_migration.c
@@ -1860,19 +1860,37 @@ static int tmigr_setup_groups(unsigned int cpu, unsigned int node,
* child to the new parents. So tmigr_active_up() activates the
* new parents while walking up from the old root to the new.
*
- * * It is ensured that @start is active, as this setup path is
- * executed in hotplug prepare callback. This is executed by an
- * already connected and !idle CPU. Even if all other CPUs go idle,
- * the CPU executing the setup will be responsible up to current top
- * level group. And the next time it goes inactive, it will release
- * the new childmask and parent to subsequent walkers through this
- * @child. Therefore propagate active state unconditionally.
+ * * It is ensured that @start is active, (or on the way to be activated
+ * by another CPU that woke up before the current one) as this setup path
+ * is executed in hotplug prepare callback. This is executed by an already
+ * connected and !idle CPU in the hierarchy.
+ *
+ * * The below RmW atomic operation ensures that:
+ *
+ * 1) If the old root has been completely activated, the latest state is
+ * acquired (the below implicit acquire pairs with the implicit release
+ * from cmpxchg() in tmigr_active_up()).
+ *
+ * 2) If the old root is still on the way to be activated, the lagging behind
+ * CPU performing the activation will acquire the links up to the new root.
+ * (The below implicit release pairs with the implicit acquire from cmpxchg()
+ * in tmigr_active_up()).
+ *
+ * 3) Every subsequent CPU below the old root will acquire the new links while
+ * walking through the old root (The below implicit release pairs with the
+ * implicit acquire from cmpxchg() in either tmigr_active_up()) or
+ * tmigr_inactive_up().
*/
- state.state = atomic_read(&start->migr_state);
- WARN_ON_ONCE(!state.active);
+ state.state = atomic_fetch_or(0, &start->migr_state);
WARN_ON_ONCE(!start->parent);
- data.childmask = start->groupmask;
- __walk_groups_from(tmigr_active_up, &data, start, start->parent);
+ /*
+ * If the state of the old root is inactive, another CPU is on its way to activate
+ * it and propagate to the new root.
+ */
+ if (state.active) {
+ data.childmask = start->groupmask;
+ __walk_groups_from(tmigr_active_up, &data, start, start->parent);
+ }
}
/* Root update */