Skip to content

Commit fa96203

Browse files
Frederic WeisbeckerKAGA-KOKO
authored andcommitted
timers/migration: Remove locking on group connection
Initializing the tmc's group, the group's number of children and the group's parent can all be done without locking because: 1) Reading the group's parent and its group mask is done locklessly. 2) The connections prepared for a given CPU hierarchy are visible to the target CPU once online, thanks to the CPU hotplug enforced memory ordering. 3) In case of a newly created upper level, the new root and its connections and initialization are made visible by the CPU which made the connections. When that CPUs goes idle in the future, the new link is published by tmigr_inactive_up() through the atomic RmW on ->migr_state. 4) If CPUs were still walking up the active hierarchy, they could observe the new root earlier. In this case the ordering is enforced by an early initialization of the group mask and by barriers that maintain address dependency as explained in: b729cc1 ("timers/migration: Fix another race between hotplug and idle entry/exit") de3ced7 ("timers/migration: Enforce group initialization visibility to tree walkers") 5) Timers are propagated by a chain of group locking from the bottom to the top. And while doing so, the tree also propagates groups links and initialization. Therefore remote expiration, which also relies on group locking, will observe those links and initialization while holding the root lock before walking the tree remotely and update remote timers. This is especially important for migrators in the active hierarchy that may observe the new root early. Therefore the locking is unnecessary at initialization. If anything, it just brings confusion. Remove it. Signed-off-by: Frederic Weisbecker <frederic@kernel.org> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Link: https://patch.msgid.link/20251024132536.39841-3-frederic@kernel.org
1 parent 6c181b5 commit fa96203

1 file changed

Lines changed: 0 additions & 10 deletions

File tree

kernel/time/timer_migration.c

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1573,9 +1573,6 @@ static void tmigr_connect_child_parent(struct tmigr_group *child,
15731573
{
15741574
struct tmigr_walk data;
15751575

1576-
raw_spin_lock_irq(&child->lock);
1577-
raw_spin_lock_nested(&parent->lock, SINGLE_DEPTH_NESTING);
1578-
15791576
if (activate) {
15801577
/*
15811578
* @child is the old top and @parent the new one. In this
@@ -1596,9 +1593,6 @@ static void tmigr_connect_child_parent(struct tmigr_group *child,
15961593
*/
15971594
smp_store_release(&child->parent, parent);
15981595

1599-
raw_spin_unlock(&parent->lock);
1600-
raw_spin_unlock_irq(&child->lock);
1601-
16021596
trace_tmigr_connect_child_parent(child);
16031597

16041598
if (!activate)
@@ -1695,13 +1689,9 @@ static int tmigr_setup_groups(unsigned int cpu, unsigned int node)
16951689
if (i == 0) {
16961690
struct tmigr_cpu *tmc = per_cpu_ptr(&tmigr_cpu, cpu);
16971691

1698-
raw_spin_lock_irq(&group->lock);
1699-
17001692
tmc->tmgroup = group;
17011693
tmc->groupmask = BIT(group->num_children++);
17021694

1703-
raw_spin_unlock_irq(&group->lock);
1704-
17051695
trace_tmigr_connect_cpu_parent(tmc);
17061696

17071697
/* There are no children that need to be connected */

0 commit comments

Comments
 (0)