summaryrefslogtreecommitdiff
path: root/kernel/time/tick-broadcast.c
diff options
context:
space:
mode:
authorJakub Kicinski <kuba@kernel.org>2026-09-17 14:24:32 -0700
committerJakub Kicinski <kuba@kernel.org>2026-09-17 14:31:42 -0700
commitf2b5c73c032bb03c48dce1072fc3edaf74c92402 (patch)
tree31766a4a370366d74deeacebdcb715a9d4372677 /kernel/time/tick-broadcast.c
parent26ee8cd69d46a14b37ba5e512084fe80d730127a (diff)
parentb5a051f6b840d48f159166ef073d3021989bfb50 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
Cross-merge networking fixes after downstream PR (net-7.3-rc4). Conflicts: net/core/neighbour.c 979aabdad8dd0 ("neighbour: Skip default parms when resumed in neightbl_dump_info().") 7b430fcfc972f ("neighbour: Don't render blackhole_netdev via RTM_GETNEIGHTBL.") fae1c59810b86 ("neighbour: Remove unnecessary net_eq().") https://lore.kernel.org/20260911173056.44ec06e0@kernel.org https://lore.kernel.org/aqfbJi7nAX4IbmnR@sirena.co.uk Adjacent changes: net/netlink/af_netlink.c ceac0de741bf ("netlink: do not free nlk->groups while lockless readers can use it") 7c0ec6288b49 ("net: Replace %pK output with 0") net/bridge/br_vlan.c 2842ce397dd0 ("net: bridge: vlan: fix bugs caused by switchdev deletion errors") 5bec8f861114 ("net: bridge: vlan: annotate lockless use of num_vlans") 2b1f8fd3118c ("net: bridge: vlan: annotate lockless vlan flags use") net/bridge/br_mst.c 18a6fe05fb6e ("net: bridge: mst: move switchdev call outside rcu") 120207a08fc0 ("net: bridge: vlan: annotate lockless use of msti") drivers/net/ethernet/stmicro/stmmac/hwif.h 90e4b849dfa6 ("net: stmmac: propagate FPE preemption-class mapping errors") 85ca3292d7a3 ("net: stmmac: Remove ARP offload code") Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'kernel/time/tick-broadcast.c')
-rw-r--r--kernel/time/tick-broadcast.c36
1 files changed, 22 insertions, 14 deletions
diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c
index 115e0bf01276..bda3d2391a60 100644
--- a/kernel/time/tick-broadcast.c
+++ b/kernel/time/tick-broadcast.c
@@ -165,23 +165,31 @@ static bool tick_set_oneshot_wakeup_device(struct clock_event_device *newdev,
*/
void tick_install_broadcast_device(struct clock_event_device *dev, int cpu)
{
- struct clock_event_device *cur = tick_broadcast_device.evtdev;
+ struct clock_event_device *cur;
- if (tick_set_oneshot_wakeup_device(dev, cpu))
- return;
+ scoped_guard(raw_spinlock_irqsave, &tick_broadcast_lock) {
- if (!tick_check_broadcast_device(cur, dev))
- return;
+ if (tick_set_oneshot_wakeup_device(dev, cpu))
+ return;
- if (!try_module_get(dev->owner))
- return;
+ cur = tick_broadcast_device.evtdev;
+ if (!tick_check_broadcast_device(cur, dev))
+ return;
- clockevents_exchange_device(cur, dev);
+ if (!try_module_get(dev->owner))
+ return;
+
+ __clockevents_exchange_device(cur, dev);
+ if (cur)
+ cur->event_handler = clockevents_handle_noop;
+ WRITE_ONCE(tick_broadcast_device.evtdev, dev);
+ if (!cpumask_empty(tick_broadcast_mask))
+ tick_broadcast_start_periodic(dev);
+ }
+
+ /* Module release must be outside of the lock */
if (cur)
- cur->event_handler = clockevents_handle_noop;
- tick_broadcast_device.evtdev = dev;
- if (!cpumask_empty(tick_broadcast_mask))
- tick_broadcast_start_periodic(dev);
+ module_put(cur->owner);
if (!(dev->features & CLOCK_EVT_FEAT_ONESHOT))
return;
@@ -1218,7 +1226,7 @@ int tick_broadcast_oneshot_active(void)
*/
bool tick_broadcast_oneshot_available(void)
{
- struct clock_event_device *bc = tick_broadcast_device.evtdev;
+ struct clock_event_device *bc = READ_ONCE(tick_broadcast_device.evtdev);
return bc ? bc->features & CLOCK_EVT_FEAT_ONESHOT : false;
}
@@ -1226,7 +1234,7 @@ bool tick_broadcast_oneshot_available(void)
#else
int __tick_broadcast_oneshot_control(enum tick_broadcast_state state)
{
- struct clock_event_device *bc = tick_broadcast_device.evtdev;
+ struct clock_event_device *bc = READ_ONCE(tick_broadcast_device.evtdev);
if (!bc || (bc->features & CLOCK_EVT_FEAT_HRTIMER))
return -EBUSY;