135728b82SThomas Gleixner // SPDX-License-Identifier: GPL-2.0
2f8381cbaSThomas Gleixner /*
3f8381cbaSThomas Gleixner * This file contains functions which emulate a local clock-event
4f8381cbaSThomas Gleixner * device via a broadcast event source.
5f8381cbaSThomas Gleixner *
6f8381cbaSThomas Gleixner * Copyright(C) 2005-2006, Thomas Gleixner <tglx@linutronix.de>
7f8381cbaSThomas Gleixner * Copyright(C) 2005-2007, Red Hat, Inc., Ingo Molnar
8f8381cbaSThomas Gleixner * Copyright(C) 2006-2007, Timesys Corp., Thomas Gleixner
9f8381cbaSThomas Gleixner */
10f8381cbaSThomas Gleixner #include <linux/cpu.h>
11f8381cbaSThomas Gleixner #include <linux/err.h>
12f8381cbaSThomas Gleixner #include <linux/hrtimer.h>
13d7b90689SRussell King #include <linux/interrupt.h>
14f8381cbaSThomas Gleixner #include <linux/percpu.h>
15f8381cbaSThomas Gleixner #include <linux/profile.h>
16f8381cbaSThomas Gleixner #include <linux/sched.h>
1712ad1000SMark Rutland #include <linux/smp.h>
18ccf33d68SThomas Gleixner #include <linux/module.h>
19f8381cbaSThomas Gleixner
20f8381cbaSThomas Gleixner #include "tick-internal.h"
21f8381cbaSThomas Gleixner
22f8381cbaSThomas Gleixner /*
23f8381cbaSThomas Gleixner * Broadcast support for broken x86 hardware, where the local apic
24f8381cbaSThomas Gleixner * timer stops in C3 state.
25f8381cbaSThomas Gleixner */
26f8381cbaSThomas Gleixner
27a52f5c56SDmitri Vorobiev static struct tick_device tick_broadcast_device;
28668802c2SWaiman Long static cpumask_var_t tick_broadcast_mask __cpumask_var_read_mostly;
29668802c2SWaiman Long static cpumask_var_t tick_broadcast_on __cpumask_var_read_mostly;
30668802c2SWaiman Long static cpumask_var_t tmpmask __cpumask_var_read_mostly;
31592a438fSThomas Gleixner static int tick_broadcast_forced;
32f8381cbaSThomas Gleixner
33668802c2SWaiman Long static __cacheline_aligned_in_smp DEFINE_RAW_SPINLOCK(tick_broadcast_lock);
34668802c2SWaiman Long
355590a536SThomas Gleixner #ifdef CONFIG_TICK_ONESHOT
36c94a8537SWill Deacon static DEFINE_PER_CPU(struct clock_event_device *, tick_oneshot_wakeup_device);
37c94a8537SWill Deacon
38f9d36cf4SThomas Gleixner static void tick_broadcast_setup_oneshot(struct clock_event_device *bc, bool from_periodic);
395590a536SThomas Gleixner static void tick_broadcast_clear_oneshot(int cpu);
40080873ceSThomas Gleixner static void tick_resume_broadcast_oneshot(struct clock_event_device *bc);
41aba09543SBorislav Petkov # ifdef CONFIG_HOTPLUG_CPU
421b72d432SThomas Gleixner static void tick_broadcast_oneshot_offline(unsigned int cpu);
43aba09543SBorislav Petkov # endif
445590a536SThomas Gleixner #else
45f9d36cf4SThomas Gleixner static inline void
tick_broadcast_setup_oneshot(struct clock_event_device * bc,bool from_periodic)46f9d36cf4SThomas Gleixner tick_broadcast_setup_oneshot(struct clock_event_device *bc, bool from_periodic) { BUG(); }
tick_broadcast_clear_oneshot(int cpu)475590a536SThomas Gleixner static inline void tick_broadcast_clear_oneshot(int cpu) { }
tick_resume_broadcast_oneshot(struct clock_event_device * bc)48080873ceSThomas Gleixner static inline void tick_resume_broadcast_oneshot(struct clock_event_device *bc) { }
49aba09543SBorislav Petkov # ifdef CONFIG_HOTPLUG_CPU
tick_broadcast_oneshot_offline(unsigned int cpu)501b72d432SThomas Gleixner static inline void tick_broadcast_oneshot_offline(unsigned int cpu) { }
515590a536SThomas Gleixner # endif
52aba09543SBorislav Petkov #endif
535590a536SThomas Gleixner
54f8381cbaSThomas Gleixner /*
55289f480aSIngo Molnar * Debugging: see timer_list.c
56289f480aSIngo Molnar */
tick_get_broadcast_device(void)57289f480aSIngo Molnar struct tick_device *tick_get_broadcast_device(void)
58289f480aSIngo Molnar {
59289f480aSIngo Molnar return &tick_broadcast_device;
60289f480aSIngo Molnar }
61289f480aSIngo Molnar
tick_get_broadcast_mask(void)626b954823SRusty Russell struct cpumask *tick_get_broadcast_mask(void)
63289f480aSIngo Molnar {
64b352bc1cSThomas Gleixner return tick_broadcast_mask;
65289f480aSIngo Molnar }
66289f480aSIngo Molnar
67245a057fSWill Deacon static struct clock_event_device *tick_get_oneshot_wakeup_device(int cpu);
68245a057fSWill Deacon
tick_get_wakeup_device(int cpu)69245a057fSWill Deacon const struct clock_event_device *tick_get_wakeup_device(int cpu)
70245a057fSWill Deacon {
71245a057fSWill Deacon return tick_get_oneshot_wakeup_device(cpu);
72245a057fSWill Deacon }
73245a057fSWill Deacon
74289f480aSIngo Molnar /*
75f8381cbaSThomas Gleixner * Start the device in periodic mode
76f8381cbaSThomas Gleixner */
tick_broadcast_start_periodic(struct clock_event_device * bc)77f8381cbaSThomas Gleixner static void tick_broadcast_start_periodic(struct clock_event_device *bc)
78f8381cbaSThomas Gleixner {
7918de5bc4SThomas Gleixner if (bc)
80f8381cbaSThomas Gleixner tick_setup_periodic(bc, 1);
81f8381cbaSThomas Gleixner }
82f8381cbaSThomas Gleixner
83f8381cbaSThomas Gleixner /*
84f8381cbaSThomas Gleixner * Check, if the device can be utilized as broadcast device:
85f8381cbaSThomas Gleixner */
tick_check_broadcast_device(struct clock_event_device * curdev,struct clock_event_device * newdev)8645cb8e01SThomas Gleixner static bool tick_check_broadcast_device(struct clock_event_device *curdev,
8745cb8e01SThomas Gleixner struct clock_event_device *newdev)
8845cb8e01SThomas Gleixner {
8945cb8e01SThomas Gleixner if ((newdev->features & CLOCK_EVT_FEAT_DUMMY) ||
90245a3496SSoren Brinkmann (newdev->features & CLOCK_EVT_FEAT_PERCPU) ||
9145cb8e01SThomas Gleixner (newdev->features & CLOCK_EVT_FEAT_C3STOP))
9245cb8e01SThomas Gleixner return false;
9345cb8e01SThomas Gleixner
9445cb8e01SThomas Gleixner if (tick_broadcast_device.mode == TICKDEV_MODE_ONESHOT &&
9545cb8e01SThomas Gleixner !(newdev->features & CLOCK_EVT_FEAT_ONESHOT))
9645cb8e01SThomas Gleixner return false;
9745cb8e01SThomas Gleixner
9845cb8e01SThomas Gleixner return !curdev || newdev->rating > curdev->rating;
9945cb8e01SThomas Gleixner }
10045cb8e01SThomas Gleixner
101c94a8537SWill Deacon #ifdef CONFIG_TICK_ONESHOT
tick_get_oneshot_wakeup_device(int cpu)102c94a8537SWill Deacon static struct clock_event_device *tick_get_oneshot_wakeup_device(int cpu)
103c94a8537SWill Deacon {
104c94a8537SWill Deacon return per_cpu(tick_oneshot_wakeup_device, cpu);
105c94a8537SWill Deacon }
106c94a8537SWill Deacon
tick_oneshot_wakeup_handler(struct clock_event_device * wd)107ea5c7f1bSWill Deacon static void tick_oneshot_wakeup_handler(struct clock_event_device *wd)
108ea5c7f1bSWill Deacon {
109ea5c7f1bSWill Deacon /*
110ea5c7f1bSWill Deacon * If we woke up early and the tick was reprogrammed in the
111ea5c7f1bSWill Deacon * meantime then this may be spurious but harmless.
112ea5c7f1bSWill Deacon */
113ea5c7f1bSWill Deacon tick_receive_broadcast();
114ea5c7f1bSWill Deacon }
115ea5c7f1bSWill Deacon
tick_set_oneshot_wakeup_device(struct clock_event_device * newdev,int cpu)116c94a8537SWill Deacon static bool tick_set_oneshot_wakeup_device(struct clock_event_device *newdev,
117c94a8537SWill Deacon int cpu)
118c94a8537SWill Deacon {
119c94a8537SWill Deacon struct clock_event_device *curdev = tick_get_oneshot_wakeup_device(cpu);
120c94a8537SWill Deacon
121c94a8537SWill Deacon if (!newdev)
122c94a8537SWill Deacon goto set_device;
123c94a8537SWill Deacon
124c94a8537SWill Deacon if ((newdev->features & CLOCK_EVT_FEAT_DUMMY) ||
125c94a8537SWill Deacon (newdev->features & CLOCK_EVT_FEAT_C3STOP))
126c94a8537SWill Deacon return false;
127c94a8537SWill Deacon
128c94a8537SWill Deacon if (!(newdev->features & CLOCK_EVT_FEAT_PERCPU) ||
129c94a8537SWill Deacon !(newdev->features & CLOCK_EVT_FEAT_ONESHOT))
130c94a8537SWill Deacon return false;
131c94a8537SWill Deacon
132c94a8537SWill Deacon if (!cpumask_equal(newdev->cpumask, cpumask_of(cpu)))
133c94a8537SWill Deacon return false;
134c94a8537SWill Deacon
135c94a8537SWill Deacon if (curdev && newdev->rating <= curdev->rating)
136c94a8537SWill Deacon return false;
137c94a8537SWill Deacon
138c94a8537SWill Deacon if (!try_module_get(newdev->owner))
139c94a8537SWill Deacon return false;
140c94a8537SWill Deacon
141ea5c7f1bSWill Deacon newdev->event_handler = tick_oneshot_wakeup_handler;
142c94a8537SWill Deacon set_device:
143c94a8537SWill Deacon clockevents_exchange_device(curdev, newdev);
144c94a8537SWill Deacon per_cpu(tick_oneshot_wakeup_device, cpu) = newdev;
145c94a8537SWill Deacon return true;
146c94a8537SWill Deacon }
147c94a8537SWill Deacon #else
tick_get_oneshot_wakeup_device(int cpu)148c94a8537SWill Deacon static struct clock_event_device *tick_get_oneshot_wakeup_device(int cpu)
149c94a8537SWill Deacon {
150c94a8537SWill Deacon return NULL;
151c94a8537SWill Deacon }
152c94a8537SWill Deacon
tick_set_oneshot_wakeup_device(struct clock_event_device * newdev,int cpu)153c94a8537SWill Deacon static bool tick_set_oneshot_wakeup_device(struct clock_event_device *newdev,
154c94a8537SWill Deacon int cpu)
155c94a8537SWill Deacon {
156c94a8537SWill Deacon return false;
157c94a8537SWill Deacon }
158c94a8537SWill Deacon #endif
159c94a8537SWill Deacon
16045cb8e01SThomas Gleixner /*
16145cb8e01SThomas Gleixner * Conditionally install/replace broadcast device
16245cb8e01SThomas Gleixner */
tick_install_broadcast_device(struct clock_event_device * dev,int cpu)163c94a8537SWill Deacon void tick_install_broadcast_device(struct clock_event_device *dev, int cpu)
164f8381cbaSThomas Gleixner {
1656f7a05d7SThomas Gleixner struct clock_event_device *cur = tick_broadcast_device.evtdev;
1666f7a05d7SThomas Gleixner
167c94a8537SWill Deacon if (tick_set_oneshot_wakeup_device(dev, cpu))
168c94a8537SWill Deacon return;
169c94a8537SWill Deacon
17045cb8e01SThomas Gleixner if (!tick_check_broadcast_device(cur, dev))
1717172a286SThomas Gleixner return;
17245cb8e01SThomas Gleixner
173ccf33d68SThomas Gleixner if (!try_module_get(dev->owner))
174ccf33d68SThomas Gleixner return;
175f8381cbaSThomas Gleixner
17645cb8e01SThomas Gleixner clockevents_exchange_device(cur, dev);
1776f7a05d7SThomas Gleixner if (cur)
1786f7a05d7SThomas Gleixner cur->event_handler = clockevents_handle_noop;
179f8381cbaSThomas Gleixner tick_broadcast_device.evtdev = dev;
180b352bc1cSThomas Gleixner if (!cpumask_empty(tick_broadcast_mask))
181f8381cbaSThomas Gleixner tick_broadcast_start_periodic(dev);
1829c336c99SJindong Yue
1839c336c99SJindong Yue if (!(dev->features & CLOCK_EVT_FEAT_ONESHOT))
1849c336c99SJindong Yue return;
1859c336c99SJindong Yue
1869c336c99SJindong Yue /*
1879c336c99SJindong Yue * If the system already runs in oneshot mode, switch the newly
1889c336c99SJindong Yue * registered broadcast device to oneshot mode explicitly.
1899c336c99SJindong Yue */
1909c336c99SJindong Yue if (tick_broadcast_oneshot_active()) {
1919c336c99SJindong Yue tick_broadcast_switch_to_oneshot();
1929c336c99SJindong Yue return;
1939c336c99SJindong Yue }
1949c336c99SJindong Yue
195c038c1c4SStephen Boyd /*
196c038c1c4SStephen Boyd * Inform all cpus about this. We might be in a situation
197c038c1c4SStephen Boyd * where we did not switch to oneshot mode because the per cpu
198c038c1c4SStephen Boyd * devices are affected by CLOCK_EVT_FEAT_C3STOP and the lack
199c038c1c4SStephen Boyd * of a oneshot capable broadcast device. Without that
200c038c1c4SStephen Boyd * notification the systems stays stuck in periodic mode
201c038c1c4SStephen Boyd * forever.
202c038c1c4SStephen Boyd */
203c038c1c4SStephen Boyd tick_clock_notify();
204f8381cbaSThomas Gleixner }
205f8381cbaSThomas Gleixner
206f8381cbaSThomas Gleixner /*
207f8381cbaSThomas Gleixner * Check, if the device is the broadcast device
208f8381cbaSThomas Gleixner */
tick_is_broadcast_device(struct clock_event_device * dev)209f8381cbaSThomas Gleixner int tick_is_broadcast_device(struct clock_event_device *dev)
210f8381cbaSThomas Gleixner {
211f8381cbaSThomas Gleixner return (dev && tick_broadcast_device.evtdev == dev);
212f8381cbaSThomas Gleixner }
213f8381cbaSThomas Gleixner
tick_broadcast_update_freq(struct clock_event_device * dev,u32 freq)214627ee794SThomas Gleixner int tick_broadcast_update_freq(struct clock_event_device *dev, u32 freq)
215627ee794SThomas Gleixner {
216627ee794SThomas Gleixner int ret = -ENODEV;
217627ee794SThomas Gleixner
218627ee794SThomas Gleixner if (tick_is_broadcast_device(dev)) {
219627ee794SThomas Gleixner raw_spin_lock(&tick_broadcast_lock);
220627ee794SThomas Gleixner ret = __clockevents_update_freq(dev, freq);
221627ee794SThomas Gleixner raw_spin_unlock(&tick_broadcast_lock);
222627ee794SThomas Gleixner }
223627ee794SThomas Gleixner return ret;
224627ee794SThomas Gleixner }
225627ee794SThomas Gleixner
226627ee794SThomas Gleixner
err_broadcast(const struct cpumask * mask)22712ad1000SMark Rutland static void err_broadcast(const struct cpumask *mask)
22812ad1000SMark Rutland {
22912ad1000SMark Rutland pr_crit_once("Failed to broadcast timer tick. Some CPUs may be unresponsive.\n");
23012ad1000SMark Rutland }
23112ad1000SMark Rutland
tick_device_setup_broadcast_func(struct clock_event_device * dev)2325d1d9a29SMark Rutland static void tick_device_setup_broadcast_func(struct clock_event_device *dev)
2335d1d9a29SMark Rutland {
2345d1d9a29SMark Rutland if (!dev->broadcast)
2355d1d9a29SMark Rutland dev->broadcast = tick_broadcast;
2365d1d9a29SMark Rutland if (!dev->broadcast) {
2375d1d9a29SMark Rutland pr_warn_once("%s depends on broadcast, but no broadcast function available\n",
2385d1d9a29SMark Rutland dev->name);
2395d1d9a29SMark Rutland dev->broadcast = err_broadcast;
2405d1d9a29SMark Rutland }
2415d1d9a29SMark Rutland }
2425d1d9a29SMark Rutland
243f8381cbaSThomas Gleixner /*
2444bf07f65SIngo Molnar * Check, if the device is dysfunctional and a placeholder, which
245f8381cbaSThomas Gleixner * needs to be handled by the broadcast device.
246f8381cbaSThomas Gleixner */
tick_device_uses_broadcast(struct clock_event_device * dev,int cpu)247f8381cbaSThomas Gleixner int tick_device_uses_broadcast(struct clock_event_device *dev, int cpu)
248f8381cbaSThomas Gleixner {
24907bd1172SThomas Gleixner struct clock_event_device *bc = tick_broadcast_device.evtdev;
250f8381cbaSThomas Gleixner unsigned long flags;
251e0454311SThomas Gleixner int ret = 0;
252f8381cbaSThomas Gleixner
253b5f91da0SThomas Gleixner raw_spin_lock_irqsave(&tick_broadcast_lock, flags);
254f8381cbaSThomas Gleixner
255f8381cbaSThomas Gleixner /*
256f8381cbaSThomas Gleixner * Devices might be registered with both periodic and oneshot
257f8381cbaSThomas Gleixner * mode disabled. This signals, that the device needs to be
258f8381cbaSThomas Gleixner * operated from the broadcast device and is a placeholder for
259f8381cbaSThomas Gleixner * the cpu local device.
260f8381cbaSThomas Gleixner */
261f8381cbaSThomas Gleixner if (!tick_device_is_functional(dev)) {
262f8381cbaSThomas Gleixner dev->event_handler = tick_handle_periodic;
2635d1d9a29SMark Rutland tick_device_setup_broadcast_func(dev);
264b352bc1cSThomas Gleixner cpumask_set_cpu(cpu, tick_broadcast_mask);
265a272dccaSStephen Boyd if (tick_broadcast_device.mode == TICKDEV_MODE_PERIODIC)
26607bd1172SThomas Gleixner tick_broadcast_start_periodic(bc);
267a272dccaSStephen Boyd else
268f9d36cf4SThomas Gleixner tick_broadcast_setup_oneshot(bc, false);
269f8381cbaSThomas Gleixner ret = 1;
2705590a536SThomas Gleixner } else {
2715590a536SThomas Gleixner /*
27207bd1172SThomas Gleixner * Clear the broadcast bit for this cpu if the
27307bd1172SThomas Gleixner * device is not power state affected.
2745590a536SThomas Gleixner */
27507bd1172SThomas Gleixner if (!(dev->features & CLOCK_EVT_FEAT_C3STOP))
276b352bc1cSThomas Gleixner cpumask_clear_cpu(cpu, tick_broadcast_mask);
27707bd1172SThomas Gleixner else
2785d1d9a29SMark Rutland tick_device_setup_broadcast_func(dev);
27907bd1172SThomas Gleixner
28007bd1172SThomas Gleixner /*
28107bd1172SThomas Gleixner * Clear the broadcast bit if the CPU is not in
28207bd1172SThomas Gleixner * periodic broadcast on state.
28307bd1172SThomas Gleixner */
28407bd1172SThomas Gleixner if (!cpumask_test_cpu(cpu, tick_broadcast_on))
28507bd1172SThomas Gleixner cpumask_clear_cpu(cpu, tick_broadcast_mask);
28607bd1172SThomas Gleixner
28707bd1172SThomas Gleixner switch (tick_broadcast_device.mode) {
28807bd1172SThomas Gleixner case TICKDEV_MODE_ONESHOT:
28907bd1172SThomas Gleixner /*
29007bd1172SThomas Gleixner * If the system is in oneshot mode we can
29107bd1172SThomas Gleixner * unconditionally clear the oneshot mask bit,
29207bd1172SThomas Gleixner * because the CPU is running and therefore
29307bd1172SThomas Gleixner * not in an idle state which causes the power
29407bd1172SThomas Gleixner * state affected device to stop. Let the
29507bd1172SThomas Gleixner * caller initialize the device.
29607bd1172SThomas Gleixner */
29707bd1172SThomas Gleixner tick_broadcast_clear_oneshot(cpu);
29807bd1172SThomas Gleixner ret = 0;
29907bd1172SThomas Gleixner break;
30007bd1172SThomas Gleixner
30107bd1172SThomas Gleixner case TICKDEV_MODE_PERIODIC:
30207bd1172SThomas Gleixner /*
30307bd1172SThomas Gleixner * If the system is in periodic mode, check
30407bd1172SThomas Gleixner * whether the broadcast device can be
30507bd1172SThomas Gleixner * switched off now.
30607bd1172SThomas Gleixner */
30707bd1172SThomas Gleixner if (cpumask_empty(tick_broadcast_mask) && bc)
30807bd1172SThomas Gleixner clockevents_shutdown(bc);
30907bd1172SThomas Gleixner /*
31007bd1172SThomas Gleixner * If we kept the cpu in the broadcast mask,
31107bd1172SThomas Gleixner * tell the caller to leave the per cpu device
31207bd1172SThomas Gleixner * in shutdown state. The periodic interrupt
313e0454311SThomas Gleixner * is delivered by the broadcast device, if
314e0454311SThomas Gleixner * the broadcast device exists and is not
315e0454311SThomas Gleixner * hrtimer based.
31607bd1172SThomas Gleixner */
317e0454311SThomas Gleixner if (bc && !(bc->features & CLOCK_EVT_FEAT_HRTIMER))
31807bd1172SThomas Gleixner ret = cpumask_test_cpu(cpu, tick_broadcast_mask);
31907bd1172SThomas Gleixner break;
32007bd1172SThomas Gleixner default:
32107bd1172SThomas Gleixner break;
3225590a536SThomas Gleixner }
3235590a536SThomas Gleixner }
324b5f91da0SThomas Gleixner raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags);
325f8381cbaSThomas Gleixner return ret;
326f8381cbaSThomas Gleixner }
327f8381cbaSThomas Gleixner
tick_receive_broadcast(void)32812572dbbSMark Rutland int tick_receive_broadcast(void)
32912572dbbSMark Rutland {
33012572dbbSMark Rutland struct tick_device *td = this_cpu_ptr(&tick_cpu_device);
33112572dbbSMark Rutland struct clock_event_device *evt = td->evtdev;
33212572dbbSMark Rutland
33312572dbbSMark Rutland if (!evt)
33412572dbbSMark Rutland return -ENODEV;
33512572dbbSMark Rutland
33612572dbbSMark Rutland if (!evt->event_handler)
33712572dbbSMark Rutland return -EINVAL;
33812572dbbSMark Rutland
33912572dbbSMark Rutland evt->event_handler(evt);
34012572dbbSMark Rutland return 0;
34112572dbbSMark Rutland }
34212572dbbSMark Rutland
343f8381cbaSThomas Gleixner /*
3446b954823SRusty Russell * Broadcast the event to the cpus, which are set in the mask (mangled).
345f8381cbaSThomas Gleixner */
tick_do_broadcast(struct cpumask * mask)3462951d5c0SThomas Gleixner static bool tick_do_broadcast(struct cpumask *mask)
347f8381cbaSThomas Gleixner {
348186e3cb8SThomas Gleixner int cpu = smp_processor_id();
349f8381cbaSThomas Gleixner struct tick_device *td;
3502951d5c0SThomas Gleixner bool local = false;
351f8381cbaSThomas Gleixner
352f8381cbaSThomas Gleixner /*
353f8381cbaSThomas Gleixner * Check, if the current cpu is in the mask
354f8381cbaSThomas Gleixner */
3556b954823SRusty Russell if (cpumask_test_cpu(cpu, mask)) {
3568eb23126SThomas Gleixner struct clock_event_device *bc = tick_broadcast_device.evtdev;
3578eb23126SThomas Gleixner
3586b954823SRusty Russell cpumask_clear_cpu(cpu, mask);
3598eb23126SThomas Gleixner /*
3608eb23126SThomas Gleixner * We only run the local handler, if the broadcast
3618eb23126SThomas Gleixner * device is not hrtimer based. Otherwise we run into
3628eb23126SThomas Gleixner * a hrtimer recursion.
3638eb23126SThomas Gleixner *
3648eb23126SThomas Gleixner * local timer_interrupt()
3658eb23126SThomas Gleixner * local_handler()
3668eb23126SThomas Gleixner * expire_hrtimers()
3678eb23126SThomas Gleixner * bc_handler()
3688eb23126SThomas Gleixner * local_handler()
3698eb23126SThomas Gleixner * expire_hrtimers()
3708eb23126SThomas Gleixner */
3718eb23126SThomas Gleixner local = !(bc->features & CLOCK_EVT_FEAT_HRTIMER);
372f8381cbaSThomas Gleixner }
373f8381cbaSThomas Gleixner
3746b954823SRusty Russell if (!cpumask_empty(mask)) {
375f8381cbaSThomas Gleixner /*
376f8381cbaSThomas Gleixner * It might be necessary to actually check whether the devices
377f8381cbaSThomas Gleixner * have different broadcast functions. For now, just use the
378f8381cbaSThomas Gleixner * one of the first device. This works as long as we have this
379f8381cbaSThomas Gleixner * misfeature only on x86 (lapic)
380f8381cbaSThomas Gleixner */
3816b954823SRusty Russell td = &per_cpu(tick_cpu_device, cpumask_first(mask));
3826b954823SRusty Russell td->evtdev->broadcast(mask);
383f8381cbaSThomas Gleixner }
3842951d5c0SThomas Gleixner return local;
385f8381cbaSThomas Gleixner }
386f8381cbaSThomas Gleixner
387f8381cbaSThomas Gleixner /*
388f8381cbaSThomas Gleixner * Periodic broadcast:
389f8381cbaSThomas Gleixner * - invoke the broadcast handlers
390f8381cbaSThomas Gleixner */
tick_do_periodic_broadcast(void)3912951d5c0SThomas Gleixner static bool tick_do_periodic_broadcast(void)
392f8381cbaSThomas Gleixner {
393b352bc1cSThomas Gleixner cpumask_and(tmpmask, cpu_online_mask, tick_broadcast_mask);
3942951d5c0SThomas Gleixner return tick_do_broadcast(tmpmask);
395f8381cbaSThomas Gleixner }
396f8381cbaSThomas Gleixner
397f8381cbaSThomas Gleixner /*
398f8381cbaSThomas Gleixner * Event handler for periodic broadcast ticks
399f8381cbaSThomas Gleixner */
tick_handle_periodic_broadcast(struct clock_event_device * dev)400f8381cbaSThomas Gleixner static void tick_handle_periodic_broadcast(struct clock_event_device *dev)
401f8381cbaSThomas Gleixner {
4022951d5c0SThomas Gleixner struct tick_device *td = this_cpu_ptr(&tick_cpu_device);
4032951d5c0SThomas Gleixner bool bc_local;
404d4496b39SThomas Gleixner
405627ee794SThomas Gleixner raw_spin_lock(&tick_broadcast_lock);
406c4288334SThomas Gleixner
407c4288334SThomas Gleixner /* Handle spurious interrupts gracefully */
408c4288334SThomas Gleixner if (clockevent_state_shutdown(tick_broadcast_device.evtdev)) {
409c4288334SThomas Gleixner raw_spin_unlock(&tick_broadcast_lock);
410c4288334SThomas Gleixner return;
411c4288334SThomas Gleixner }
412c4288334SThomas Gleixner
4132951d5c0SThomas Gleixner bc_local = tick_do_periodic_broadcast();
414627ee794SThomas Gleixner
415472c4a94SViresh Kumar if (clockevent_state_oneshot(dev)) {
416b9965449SThomas Gleixner ktime_t next = ktime_add_ns(dev->next_event, TICK_NSEC);
417f8381cbaSThomas Gleixner
4182951d5c0SThomas Gleixner clockevents_program_event(dev, next, true);
419f8381cbaSThomas Gleixner }
420627ee794SThomas Gleixner raw_spin_unlock(&tick_broadcast_lock);
4212951d5c0SThomas Gleixner
4222951d5c0SThomas Gleixner /*
4232951d5c0SThomas Gleixner * We run the handler of the local cpu after dropping
4242951d5c0SThomas Gleixner * tick_broadcast_lock because the handler might deadlock when
4252951d5c0SThomas Gleixner * trying to switch to oneshot mode.
4262951d5c0SThomas Gleixner */
4272951d5c0SThomas Gleixner if (bc_local)
4282951d5c0SThomas Gleixner td->evtdev->event_handler(td->evtdev);
429f8381cbaSThomas Gleixner }
430f8381cbaSThomas Gleixner
431592a438fSThomas Gleixner /**
432592a438fSThomas Gleixner * tick_broadcast_control - Enable/disable or force broadcast mode
433592a438fSThomas Gleixner * @mode: The selected broadcast mode
434592a438fSThomas Gleixner *
435592a438fSThomas Gleixner * Called when the system enters a state where affected tick devices
436592a438fSThomas Gleixner * might stop. Note: TICK_BROADCAST_FORCE cannot be undone.
437f8381cbaSThomas Gleixner */
tick_broadcast_control(enum tick_broadcast_mode mode)438592a438fSThomas Gleixner void tick_broadcast_control(enum tick_broadcast_mode mode)
439f8381cbaSThomas Gleixner {
440f8381cbaSThomas Gleixner struct clock_event_device *bc, *dev;
441f8381cbaSThomas Gleixner struct tick_device *td;
4429c17bcdaSThomas Gleixner int cpu, bc_stopped;
443202461e2SMike Galbraith unsigned long flags;
444f8381cbaSThomas Gleixner
445202461e2SMike Galbraith /* Protects also the local clockevent device. */
446202461e2SMike Galbraith raw_spin_lock_irqsave(&tick_broadcast_lock, flags);
447592a438fSThomas Gleixner td = this_cpu_ptr(&tick_cpu_device);
448f8381cbaSThomas Gleixner dev = td->evtdev;
449f8381cbaSThomas Gleixner
450f8381cbaSThomas Gleixner /*
4511595f452SThomas Gleixner * Is the device not affected by the powerstate ?
452f8381cbaSThomas Gleixner */
4531595f452SThomas Gleixner if (!dev || !(dev->features & CLOCK_EVT_FEAT_C3STOP))
454202461e2SMike Galbraith goto out;
455f8381cbaSThomas Gleixner
4563dfbc884SThomas Gleixner if (!tick_device_is_functional(dev))
457202461e2SMike Galbraith goto out;
4581595f452SThomas Gleixner
459592a438fSThomas Gleixner cpu = smp_processor_id();
460592a438fSThomas Gleixner bc = tick_broadcast_device.evtdev;
461b352bc1cSThomas Gleixner bc_stopped = cpumask_empty(tick_broadcast_mask);
4629c17bcdaSThomas Gleixner
463592a438fSThomas Gleixner switch (mode) {
464592a438fSThomas Gleixner case TICK_BROADCAST_FORCE:
465592a438fSThomas Gleixner tick_broadcast_forced = 1;
466df561f66SGustavo A. R. Silva fallthrough;
467592a438fSThomas Gleixner case TICK_BROADCAST_ON:
46807bd1172SThomas Gleixner cpumask_set_cpu(cpu, tick_broadcast_on);
469b352bc1cSThomas Gleixner if (!cpumask_test_and_set_cpu(cpu, tick_broadcast_mask)) {
470e0454311SThomas Gleixner /*
471e0454311SThomas Gleixner * Only shutdown the cpu local device, if:
472e0454311SThomas Gleixner *
473e0454311SThomas Gleixner * - the broadcast device exists
474e0454311SThomas Gleixner * - the broadcast device is not a hrtimer based one
475e0454311SThomas Gleixner * - the broadcast device is in periodic mode to
4764bf07f65SIngo Molnar * avoid a hiccup during switch to oneshot mode
477e0454311SThomas Gleixner */
478e0454311SThomas Gleixner if (bc && !(bc->features & CLOCK_EVT_FEAT_HRTIMER) &&
479e0454311SThomas Gleixner tick_broadcast_device.mode == TICKDEV_MODE_PERIODIC)
4802344abbcSThomas Gleixner clockevents_shutdown(dev);
481f8381cbaSThomas Gleixner }
4821595f452SThomas Gleixner break;
483592a438fSThomas Gleixner
484592a438fSThomas Gleixner case TICK_BROADCAST_OFF:
485592a438fSThomas Gleixner if (tick_broadcast_forced)
48607bd1172SThomas Gleixner break;
48707bd1172SThomas Gleixner cpumask_clear_cpu(cpu, tick_broadcast_on);
48807bd1172SThomas Gleixner if (cpumask_test_and_clear_cpu(cpu, tick_broadcast_mask)) {
48907454bffSThomas Gleixner if (tick_broadcast_device.mode ==
49007454bffSThomas Gleixner TICKDEV_MODE_PERIODIC)
491f8381cbaSThomas Gleixner tick_setup_periodic(dev, 0);
492f8381cbaSThomas Gleixner }
4931595f452SThomas Gleixner break;
494f8381cbaSThomas Gleixner }
495f8381cbaSThomas Gleixner
496c4d029f2SThomas Gleixner if (bc) {
497b352bc1cSThomas Gleixner if (cpumask_empty(tick_broadcast_mask)) {
4989c17bcdaSThomas Gleixner if (!bc_stopped)
4992344abbcSThomas Gleixner clockevents_shutdown(bc);
5009c17bcdaSThomas Gleixner } else if (bc_stopped) {
501f8381cbaSThomas Gleixner if (tick_broadcast_device.mode == TICKDEV_MODE_PERIODIC)
502f8381cbaSThomas Gleixner tick_broadcast_start_periodic(bc);
50379bf2bb3SThomas Gleixner else
504f9d36cf4SThomas Gleixner tick_broadcast_setup_oneshot(bc, false);
505f8381cbaSThomas Gleixner }
506c4d029f2SThomas Gleixner }
507202461e2SMike Galbraith out:
508202461e2SMike Galbraith raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags);
509f8381cbaSThomas Gleixner }
510592a438fSThomas Gleixner EXPORT_SYMBOL_GPL(tick_broadcast_control);
511f8381cbaSThomas Gleixner
512f8381cbaSThomas Gleixner /*
513f8381cbaSThomas Gleixner * Set the periodic handler depending on broadcast on/off
514f8381cbaSThomas Gleixner */
tick_set_periodic_handler(struct clock_event_device * dev,int broadcast)515f8381cbaSThomas Gleixner void tick_set_periodic_handler(struct clock_event_device *dev, int broadcast)
516f8381cbaSThomas Gleixner {
517f8381cbaSThomas Gleixner if (!broadcast)
518f8381cbaSThomas Gleixner dev->event_handler = tick_handle_periodic;
519f8381cbaSThomas Gleixner else
520f8381cbaSThomas Gleixner dev->event_handler = tick_handle_periodic_broadcast;
521f8381cbaSThomas Gleixner }
522f8381cbaSThomas Gleixner
523a49b116dSThomas Gleixner #ifdef CONFIG_HOTPLUG_CPU
tick_shutdown_broadcast(void)5241b72d432SThomas Gleixner static void tick_shutdown_broadcast(void)
525f8381cbaSThomas Gleixner {
5261b72d432SThomas Gleixner struct clock_event_device *bc = tick_broadcast_device.evtdev;
527f8381cbaSThomas Gleixner
528f8381cbaSThomas Gleixner if (tick_broadcast_device.mode == TICKDEV_MODE_PERIODIC) {
529b352bc1cSThomas Gleixner if (bc && cpumask_empty(tick_broadcast_mask))
5302344abbcSThomas Gleixner clockevents_shutdown(bc);
531f8381cbaSThomas Gleixner }
532f8381cbaSThomas Gleixner }
5331b72d432SThomas Gleixner
5341b72d432SThomas Gleixner /*
5351b72d432SThomas Gleixner * Remove a CPU from broadcasting
5361b72d432SThomas Gleixner */
tick_broadcast_offline(unsigned int cpu)5371b72d432SThomas Gleixner void tick_broadcast_offline(unsigned int cpu)
5381b72d432SThomas Gleixner {
5391b72d432SThomas Gleixner raw_spin_lock(&tick_broadcast_lock);
5401b72d432SThomas Gleixner cpumask_clear_cpu(cpu, tick_broadcast_mask);
5411b72d432SThomas Gleixner cpumask_clear_cpu(cpu, tick_broadcast_on);
5421b72d432SThomas Gleixner tick_broadcast_oneshot_offline(cpu);
5431b72d432SThomas Gleixner tick_shutdown_broadcast();
5441b72d432SThomas Gleixner raw_spin_unlock(&tick_broadcast_lock);
5451b72d432SThomas Gleixner }
5461b72d432SThomas Gleixner
547a49b116dSThomas Gleixner #endif
54879bf2bb3SThomas Gleixner
tick_suspend_broadcast(void)5496321dd60SThomas Gleixner void tick_suspend_broadcast(void)
5506321dd60SThomas Gleixner {
5516321dd60SThomas Gleixner struct clock_event_device *bc;
5526321dd60SThomas Gleixner unsigned long flags;
5536321dd60SThomas Gleixner
554b5f91da0SThomas Gleixner raw_spin_lock_irqsave(&tick_broadcast_lock, flags);
5556321dd60SThomas Gleixner
5566321dd60SThomas Gleixner bc = tick_broadcast_device.evtdev;
55718de5bc4SThomas Gleixner if (bc)
5582344abbcSThomas Gleixner clockevents_shutdown(bc);
5596321dd60SThomas Gleixner
560b5f91da0SThomas Gleixner raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags);
5616321dd60SThomas Gleixner }
5626321dd60SThomas Gleixner
563f46481d0SThomas Gleixner /*
564f46481d0SThomas Gleixner * This is called from tick_resume_local() on a resuming CPU. That's
565f46481d0SThomas Gleixner * called from the core resume function, tick_unfreeze() and the magic XEN
566f46481d0SThomas Gleixner * resume hackery.
567f46481d0SThomas Gleixner *
568f46481d0SThomas Gleixner * In none of these cases the broadcast device mode can change and the
569f46481d0SThomas Gleixner * bit of the resuming CPU in the broadcast mask is safe as well.
570f46481d0SThomas Gleixner */
tick_resume_check_broadcast(void)571f46481d0SThomas Gleixner bool tick_resume_check_broadcast(void)
572f46481d0SThomas Gleixner {
573f46481d0SThomas Gleixner if (tick_broadcast_device.mode == TICKDEV_MODE_ONESHOT)
574f46481d0SThomas Gleixner return false;
575f46481d0SThomas Gleixner else
576f46481d0SThomas Gleixner return cpumask_test_cpu(smp_processor_id(), tick_broadcast_mask);
577f46481d0SThomas Gleixner }
578f46481d0SThomas Gleixner
tick_resume_broadcast(void)579f46481d0SThomas Gleixner void tick_resume_broadcast(void)
5806321dd60SThomas Gleixner {
5816321dd60SThomas Gleixner struct clock_event_device *bc;
5826321dd60SThomas Gleixner unsigned long flags;
5836321dd60SThomas Gleixner
584b5f91da0SThomas Gleixner raw_spin_lock_irqsave(&tick_broadcast_lock, flags);
5856321dd60SThomas Gleixner
5866321dd60SThomas Gleixner bc = tick_broadcast_device.evtdev;
5876321dd60SThomas Gleixner
588cd05a1f8SThomas Gleixner if (bc) {
589554ef387SViresh Kumar clockevents_tick_resume(bc);
59018de5bc4SThomas Gleixner
591cd05a1f8SThomas Gleixner switch (tick_broadcast_device.mode) {
592cd05a1f8SThomas Gleixner case TICKDEV_MODE_PERIODIC:
593b352bc1cSThomas Gleixner if (!cpumask_empty(tick_broadcast_mask))
594cd05a1f8SThomas Gleixner tick_broadcast_start_periodic(bc);
595cd05a1f8SThomas Gleixner break;
596cd05a1f8SThomas Gleixner case TICKDEV_MODE_ONESHOT:
597b352bc1cSThomas Gleixner if (!cpumask_empty(tick_broadcast_mask))
598080873ceSThomas Gleixner tick_resume_broadcast_oneshot(bc);
599cd05a1f8SThomas Gleixner break;
600cd05a1f8SThomas Gleixner }
6016321dd60SThomas Gleixner }
602b5f91da0SThomas Gleixner raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags);
6036321dd60SThomas Gleixner }
6046321dd60SThomas Gleixner
60579bf2bb3SThomas Gleixner #ifdef CONFIG_TICK_ONESHOT
60679bf2bb3SThomas Gleixner
607668802c2SWaiman Long static cpumask_var_t tick_broadcast_oneshot_mask __cpumask_var_read_mostly;
608668802c2SWaiman Long static cpumask_var_t tick_broadcast_pending_mask __cpumask_var_read_mostly;
609668802c2SWaiman Long static cpumask_var_t tick_broadcast_force_mask __cpumask_var_read_mostly;
61079bf2bb3SThomas Gleixner
611289f480aSIngo Molnar /*
6126b954823SRusty Russell * Exposed for debugging: see timer_list.c
613289f480aSIngo Molnar */
tick_get_broadcast_oneshot_mask(void)6146b954823SRusty Russell struct cpumask *tick_get_broadcast_oneshot_mask(void)
615289f480aSIngo Molnar {
616b352bc1cSThomas Gleixner return tick_broadcast_oneshot_mask;
617289f480aSIngo Molnar }
618289f480aSIngo Molnar
619d2348fb6SDaniel Lezcano /*
620eaa907c5SThomas Gleixner * Called before going idle with interrupts disabled. Checks whether a
621eaa907c5SThomas Gleixner * broadcast event from the other core is about to happen. We detected
622eaa907c5SThomas Gleixner * that in tick_broadcast_oneshot_control(). The callsite can use this
623eaa907c5SThomas Gleixner * to avoid a deep idle transition as we are about to get the
624eaa907c5SThomas Gleixner * broadcast IPI right away.
625eaa907c5SThomas Gleixner */
tick_check_broadcast_expired(void)626a01353cfSPeter Zijlstra noinstr int tick_check_broadcast_expired(void)
627eaa907c5SThomas Gleixner {
628a01353cfSPeter Zijlstra #ifdef _ASM_GENERIC_BITOPS_INSTRUMENTED_NON_ATOMIC_H
629a01353cfSPeter Zijlstra return arch_test_bit(smp_processor_id(), cpumask_bits(tick_broadcast_force_mask));
630a01353cfSPeter Zijlstra #else
631eaa907c5SThomas Gleixner return cpumask_test_cpu(smp_processor_id(), tick_broadcast_force_mask);
632a01353cfSPeter Zijlstra #endif
633eaa907c5SThomas Gleixner }
634eaa907c5SThomas Gleixner
635eaa907c5SThomas Gleixner /*
636d2348fb6SDaniel Lezcano * Set broadcast interrupt affinity
637d2348fb6SDaniel Lezcano */
tick_broadcast_set_affinity(struct clock_event_device * bc,const struct cpumask * cpumask)638d2348fb6SDaniel Lezcano static void tick_broadcast_set_affinity(struct clock_event_device *bc,
639d2348fb6SDaniel Lezcano const struct cpumask *cpumask)
640d2348fb6SDaniel Lezcano {
641d2348fb6SDaniel Lezcano if (!(bc->features & CLOCK_EVT_FEAT_DYNIRQ))
642d2348fb6SDaniel Lezcano return;
643d2348fb6SDaniel Lezcano
644d2348fb6SDaniel Lezcano if (cpumask_equal(bc->cpumask, cpumask))
645d2348fb6SDaniel Lezcano return;
646d2348fb6SDaniel Lezcano
647d2348fb6SDaniel Lezcano bc->cpumask = cpumask;
648d2348fb6SDaniel Lezcano irq_set_affinity(bc->irq, bc->cpumask);
649d2348fb6SDaniel Lezcano }
650d2348fb6SDaniel Lezcano
tick_broadcast_set_event(struct clock_event_device * bc,int cpu,ktime_t expires)651298dbd1cSThomas Gleixner static void tick_broadcast_set_event(struct clock_event_device *bc, int cpu,
652298dbd1cSThomas Gleixner ktime_t expires)
65379bf2bb3SThomas Gleixner {
654472c4a94SViresh Kumar if (!clockevent_state_oneshot(bc))
655d7eb231cSThomas Gleixner clockevents_switch_state(bc, CLOCK_EVT_STATE_ONESHOT);
656b9a6a235SThomas Gleixner
657298dbd1cSThomas Gleixner clockevents_program_event(bc, expires, 1);
658d2348fb6SDaniel Lezcano tick_broadcast_set_affinity(bc, cpumask_of(cpu));
65979bf2bb3SThomas Gleixner }
66079bf2bb3SThomas Gleixner
tick_resume_broadcast_oneshot(struct clock_event_device * bc)661080873ceSThomas Gleixner static void tick_resume_broadcast_oneshot(struct clock_event_device *bc)
662cd05a1f8SThomas Gleixner {
663d7eb231cSThomas Gleixner clockevents_switch_state(bc, CLOCK_EVT_STATE_ONESHOT);
664cd05a1f8SThomas Gleixner }
665cd05a1f8SThomas Gleixner
66679bf2bb3SThomas Gleixner /*
667fb02fbc1SThomas Gleixner * Called from irq_enter() when idle was interrupted to reenable the
668fb02fbc1SThomas Gleixner * per cpu device.
669fb02fbc1SThomas Gleixner */
tick_check_oneshot_broadcast_this_cpu(void)670e8fcaa5cSFrederic Weisbecker void tick_check_oneshot_broadcast_this_cpu(void)
671fb02fbc1SThomas Gleixner {
672e8fcaa5cSFrederic Weisbecker if (cpumask_test_cpu(smp_processor_id(), tick_broadcast_oneshot_mask)) {
67322127e93SChristoph Lameter struct tick_device *td = this_cpu_ptr(&tick_cpu_device);
674fb02fbc1SThomas Gleixner
6751f73a980SThomas Gleixner /*
6761f73a980SThomas Gleixner * We might be in the middle of switching over from
6771f73a980SThomas Gleixner * periodic to oneshot. If the CPU has not yet
6781f73a980SThomas Gleixner * switched over, leave the device alone.
6791f73a980SThomas Gleixner */
6801f73a980SThomas Gleixner if (td->mode == TICKDEV_MODE_ONESHOT) {
681d7eb231cSThomas Gleixner clockevents_switch_state(td->evtdev,
68277e32c89SViresh Kumar CLOCK_EVT_STATE_ONESHOT);
6831f73a980SThomas Gleixner }
684fb02fbc1SThomas Gleixner }
685fb02fbc1SThomas Gleixner }
686fb02fbc1SThomas Gleixner
687fb02fbc1SThomas Gleixner /*
68879bf2bb3SThomas Gleixner * Handle oneshot mode broadcasting
68979bf2bb3SThomas Gleixner */
tick_handle_oneshot_broadcast(struct clock_event_device * dev)69079bf2bb3SThomas Gleixner static void tick_handle_oneshot_broadcast(struct clock_event_device *dev)
69179bf2bb3SThomas Gleixner {
69279bf2bb3SThomas Gleixner struct tick_device *td;
693cdc6f27dSThomas Gleixner ktime_t now, next_event;
694d2348fb6SDaniel Lezcano int cpu, next_cpu = 0;
695298dbd1cSThomas Gleixner bool bc_local;
69679bf2bb3SThomas Gleixner
697b5f91da0SThomas Gleixner raw_spin_lock(&tick_broadcast_lock);
6982456e855SThomas Gleixner dev->next_event = KTIME_MAX;
6992456e855SThomas Gleixner next_event = KTIME_MAX;
700b352bc1cSThomas Gleixner cpumask_clear(tmpmask);
70179bf2bb3SThomas Gleixner now = ktime_get();
70279bf2bb3SThomas Gleixner /* Find all expired events */
703b352bc1cSThomas Gleixner for_each_cpu(cpu, tick_broadcast_oneshot_mask) {
7045596fe34SDexuan Cui /*
7055596fe34SDexuan Cui * Required for !SMP because for_each_cpu() reports
7065596fe34SDexuan Cui * unconditionally CPU0 as set on UP kernels.
7075596fe34SDexuan Cui */
7085596fe34SDexuan Cui if (!IS_ENABLED(CONFIG_SMP) &&
7095596fe34SDexuan Cui cpumask_empty(tick_broadcast_oneshot_mask))
7105596fe34SDexuan Cui break;
7115596fe34SDexuan Cui
71279bf2bb3SThomas Gleixner td = &per_cpu(tick_cpu_device, cpu);
7132456e855SThomas Gleixner if (td->evtdev->next_event <= now) {
714b352bc1cSThomas Gleixner cpumask_set_cpu(cpu, tmpmask);
71526517f3eSThomas Gleixner /*
71626517f3eSThomas Gleixner * Mark the remote cpu in the pending mask, so
71726517f3eSThomas Gleixner * it can avoid reprogramming the cpu local
71826517f3eSThomas Gleixner * timer in tick_broadcast_oneshot_control().
71926517f3eSThomas Gleixner */
72026517f3eSThomas Gleixner cpumask_set_cpu(cpu, tick_broadcast_pending_mask);
7212456e855SThomas Gleixner } else if (td->evtdev->next_event < next_event) {
7222456e855SThomas Gleixner next_event = td->evtdev->next_event;
723d2348fb6SDaniel Lezcano next_cpu = cpu;
724d2348fb6SDaniel Lezcano }
72579bf2bb3SThomas Gleixner }
72679bf2bb3SThomas Gleixner
7272938d275SThomas Gleixner /*
7282938d275SThomas Gleixner * Remove the current cpu from the pending mask. The event is
7292938d275SThomas Gleixner * delivered immediately in tick_do_broadcast() !
7302938d275SThomas Gleixner */
7312938d275SThomas Gleixner cpumask_clear_cpu(smp_processor_id(), tick_broadcast_pending_mask);
7322938d275SThomas Gleixner
733989dcb64SThomas Gleixner /* Take care of enforced broadcast requests */
734989dcb64SThomas Gleixner cpumask_or(tmpmask, tmpmask, tick_broadcast_force_mask);
735989dcb64SThomas Gleixner cpumask_clear(tick_broadcast_force_mask);
736989dcb64SThomas Gleixner
73779bf2bb3SThomas Gleixner /*
738c9b5a266SThomas Gleixner * Sanity check. Catch the case where we try to broadcast to
739c9b5a266SThomas Gleixner * offline cpus.
740c9b5a266SThomas Gleixner */
741c9b5a266SThomas Gleixner if (WARN_ON_ONCE(!cpumask_subset(tmpmask, cpu_online_mask)))
742c9b5a266SThomas Gleixner cpumask_and(tmpmask, tmpmask, cpu_online_mask);
743c9b5a266SThomas Gleixner
744c9b5a266SThomas Gleixner /*
745298dbd1cSThomas Gleixner * Wakeup the cpus which have an expired event.
74679bf2bb3SThomas Gleixner */
747298dbd1cSThomas Gleixner bc_local = tick_do_broadcast(tmpmask);
748cdc6f27dSThomas Gleixner
74979bf2bb3SThomas Gleixner /*
750cdc6f27dSThomas Gleixner * Two reasons for reprogram:
751cdc6f27dSThomas Gleixner *
752cdc6f27dSThomas Gleixner * - The global event did not expire any CPU local
753cdc6f27dSThomas Gleixner * events. This happens in dyntick mode, as the maximum PIT
754cdc6f27dSThomas Gleixner * delta is quite small.
755cdc6f27dSThomas Gleixner *
756cdc6f27dSThomas Gleixner * - There are pending events on sleeping CPUs which were not
757cdc6f27dSThomas Gleixner * in the event mask
75879bf2bb3SThomas Gleixner */
7592456e855SThomas Gleixner if (next_event != KTIME_MAX)
760298dbd1cSThomas Gleixner tick_broadcast_set_event(dev, next_cpu, next_event);
761298dbd1cSThomas Gleixner
762b5f91da0SThomas Gleixner raw_spin_unlock(&tick_broadcast_lock);
763298dbd1cSThomas Gleixner
764298dbd1cSThomas Gleixner if (bc_local) {
765298dbd1cSThomas Gleixner td = this_cpu_ptr(&tick_cpu_device);
766298dbd1cSThomas Gleixner td->evtdev->event_handler(td->evtdev);
767298dbd1cSThomas Gleixner }
76879bf2bb3SThomas Gleixner }
76979bf2bb3SThomas Gleixner
broadcast_needs_cpu(struct clock_event_device * bc,int cpu)7705d1638acSPreeti U Murthy static int broadcast_needs_cpu(struct clock_event_device *bc, int cpu)
7715d1638acSPreeti U Murthy {
7725d1638acSPreeti U Murthy if (!(bc->features & CLOCK_EVT_FEAT_HRTIMER))
7735d1638acSPreeti U Murthy return 0;
7742456e855SThomas Gleixner if (bc->next_event == KTIME_MAX)
7755d1638acSPreeti U Murthy return 0;
7765d1638acSPreeti U Murthy return bc->bound_on == cpu ? -EBUSY : 0;
7775d1638acSPreeti U Murthy }
7785d1638acSPreeti U Murthy
broadcast_shutdown_local(struct clock_event_device * bc,struct clock_event_device * dev)7795d1638acSPreeti U Murthy static void broadcast_shutdown_local(struct clock_event_device *bc,
7805d1638acSPreeti U Murthy struct clock_event_device *dev)
7815d1638acSPreeti U Murthy {
7825d1638acSPreeti U Murthy /*
7835d1638acSPreeti U Murthy * For hrtimer based broadcasting we cannot shutdown the cpu
7845d1638acSPreeti U Murthy * local device if our own event is the first one to expire or
7855d1638acSPreeti U Murthy * if we own the broadcast timer.
7865d1638acSPreeti U Murthy */
7875d1638acSPreeti U Murthy if (bc->features & CLOCK_EVT_FEAT_HRTIMER) {
7885d1638acSPreeti U Murthy if (broadcast_needs_cpu(bc, smp_processor_id()))
7895d1638acSPreeti U Murthy return;
7902456e855SThomas Gleixner if (dev->next_event < bc->next_event)
7915d1638acSPreeti U Murthy return;
7925d1638acSPreeti U Murthy }
793d7eb231cSThomas Gleixner clockevents_switch_state(dev, CLOCK_EVT_STATE_SHUTDOWN);
7945d1638acSPreeti U Murthy }
7955d1638acSPreeti U Murthy
___tick_broadcast_oneshot_control(enum tick_broadcast_state state,struct tick_device * td,int cpu)796e5007c28SWill Deacon static int ___tick_broadcast_oneshot_control(enum tick_broadcast_state state,
797e5007c28SWill Deacon struct tick_device *td,
798e5007c28SWill Deacon int cpu)
79979bf2bb3SThomas Gleixner {
800e5007c28SWill Deacon struct clock_event_device *bc, *dev = td->evtdev;
801e5007c28SWill Deacon int ret = 0;
8021fe5d5c3SThomas Gleixner ktime_t now;
80379bf2bb3SThomas Gleixner
8041fe5d5c3SThomas Gleixner raw_spin_lock(&tick_broadcast_lock);
8057372b0b1SAndi Kleen bc = tick_broadcast_device.evtdev;
8067372b0b1SAndi Kleen
8071fe5d5c3SThomas Gleixner if (state == TICK_BROADCAST_ENTER) {
808e3ac79e0SThomas Gleixner /*
809d5113e13SThomas Gleixner * If the current CPU owns the hrtimer broadcast
810d5113e13SThomas Gleixner * mechanism, it cannot go deep idle and we do not add
811d5113e13SThomas Gleixner * the CPU to the broadcast mask. We don't have to go
812d5113e13SThomas Gleixner * through the EXIT path as the local timer is not
813d5113e13SThomas Gleixner * shutdown.
814d5113e13SThomas Gleixner */
815d5113e13SThomas Gleixner ret = broadcast_needs_cpu(bc, cpu);
816d5113e13SThomas Gleixner if (ret)
817d5113e13SThomas Gleixner goto out;
818d5113e13SThomas Gleixner
819d5113e13SThomas Gleixner /*
820e3ac79e0SThomas Gleixner * If the broadcast device is in periodic mode, we
821e3ac79e0SThomas Gleixner * return.
822e3ac79e0SThomas Gleixner */
823d3325726SThomas Gleixner if (tick_broadcast_device.mode == TICKDEV_MODE_PERIODIC) {
824d3325726SThomas Gleixner /* If it is a hrtimer based broadcast, return busy */
825d3325726SThomas Gleixner if (bc->features & CLOCK_EVT_FEAT_HRTIMER)
826d3325726SThomas Gleixner ret = -EBUSY;
827e3ac79e0SThomas Gleixner goto out;
828d3325726SThomas Gleixner }
829e3ac79e0SThomas Gleixner
830b352bc1cSThomas Gleixner if (!cpumask_test_and_set_cpu(cpu, tick_broadcast_oneshot_mask)) {
8312938d275SThomas Gleixner WARN_ON_ONCE(cpumask_test_cpu(cpu, tick_broadcast_pending_mask));
832d5113e13SThomas Gleixner
833d5113e13SThomas Gleixner /* Conditionally shut down the local timer. */
8345d1638acSPreeti U Murthy broadcast_shutdown_local(bc, dev);
835d5113e13SThomas Gleixner
836989dcb64SThomas Gleixner /*
837989dcb64SThomas Gleixner * We only reprogram the broadcast timer if we
838989dcb64SThomas Gleixner * did not mark ourself in the force mask and
839989dcb64SThomas Gleixner * if the cpu local event is earlier than the
840989dcb64SThomas Gleixner * broadcast event. If the current CPU is in
841989dcb64SThomas Gleixner * the force mask, then we are going to be
8420cc5281aSThomas Gleixner * woken by the IPI right away; we return
8430cc5281aSThomas Gleixner * busy, so the CPU does not try to go deep
8440cc5281aSThomas Gleixner * idle.
845989dcb64SThomas Gleixner */
8460cc5281aSThomas Gleixner if (cpumask_test_cpu(cpu, tick_broadcast_force_mask)) {
8470cc5281aSThomas Gleixner ret = -EBUSY;
8482456e855SThomas Gleixner } else if (dev->next_event < bc->next_event) {
849298dbd1cSThomas Gleixner tick_broadcast_set_event(bc, cpu, dev->next_event);
8505d1638acSPreeti U Murthy /*
851d5113e13SThomas Gleixner * In case of hrtimer broadcasts the
852d5113e13SThomas Gleixner * programming might have moved the
853d5113e13SThomas Gleixner * timer to this cpu. If yes, remove
854d5113e13SThomas Gleixner * us from the broadcast mask and
855d5113e13SThomas Gleixner * return busy.
8565d1638acSPreeti U Murthy */
8575d1638acSPreeti U Murthy ret = broadcast_needs_cpu(bc, cpu);
858d5113e13SThomas Gleixner if (ret) {
859d5113e13SThomas Gleixner cpumask_clear_cpu(cpu,
860d5113e13SThomas Gleixner tick_broadcast_oneshot_mask);
861d5113e13SThomas Gleixner }
862d5113e13SThomas Gleixner }
863d5113e13SThomas Gleixner }
86479bf2bb3SThomas Gleixner } else {
865b352bc1cSThomas Gleixner if (cpumask_test_and_clear_cpu(cpu, tick_broadcast_oneshot_mask)) {
866d7eb231cSThomas Gleixner clockevents_switch_state(dev, CLOCK_EVT_STATE_ONESHOT);
86726517f3eSThomas Gleixner /*
86826517f3eSThomas Gleixner * The cpu which was handling the broadcast
86926517f3eSThomas Gleixner * timer marked this cpu in the broadcast
87026517f3eSThomas Gleixner * pending mask and fired the broadcast
87126517f3eSThomas Gleixner * IPI. So we are going to handle the expired
87226517f3eSThomas Gleixner * event anyway via the broadcast IPI
87326517f3eSThomas Gleixner * handler. No need to reprogram the timer
87426517f3eSThomas Gleixner * with an already expired event.
87526517f3eSThomas Gleixner */
87626517f3eSThomas Gleixner if (cpumask_test_and_clear_cpu(cpu,
87726517f3eSThomas Gleixner tick_broadcast_pending_mask))
87826517f3eSThomas Gleixner goto out;
87926517f3eSThomas Gleixner
880989dcb64SThomas Gleixner /*
881ea8deb8dSDaniel Lezcano * Bail out if there is no next event.
882ea8deb8dSDaniel Lezcano */
8832456e855SThomas Gleixner if (dev->next_event == KTIME_MAX)
884ea8deb8dSDaniel Lezcano goto out;
885ea8deb8dSDaniel Lezcano /*
886989dcb64SThomas Gleixner * If the pending bit is not set, then we are
887989dcb64SThomas Gleixner * either the CPU handling the broadcast
888989dcb64SThomas Gleixner * interrupt or we got woken by something else.
889989dcb64SThomas Gleixner *
89013e792a1SLaurent Gauthier * We are no longer in the broadcast mask, so
891989dcb64SThomas Gleixner * if the cpu local expiry time is already
892989dcb64SThomas Gleixner * reached, we would reprogram the cpu local
893989dcb64SThomas Gleixner * timer with an already expired event.
894989dcb64SThomas Gleixner *
895989dcb64SThomas Gleixner * This can lead to a ping-pong when we return
89613e792a1SLaurent Gauthier * to idle and therefore rearm the broadcast
897989dcb64SThomas Gleixner * timer before the cpu local timer was able
898989dcb64SThomas Gleixner * to fire. This happens because the forced
899989dcb64SThomas Gleixner * reprogramming makes sure that the event
900989dcb64SThomas Gleixner * will happen in the future and depending on
901989dcb64SThomas Gleixner * the min_delta setting this might be far
902989dcb64SThomas Gleixner * enough out that the ping-pong starts.
903989dcb64SThomas Gleixner *
904989dcb64SThomas Gleixner * If the cpu local next_event has expired
905989dcb64SThomas Gleixner * then we know that the broadcast timer
906989dcb64SThomas Gleixner * next_event has expired as well and
907989dcb64SThomas Gleixner * broadcast is about to be handled. So we
908989dcb64SThomas Gleixner * avoid reprogramming and enforce that the
909989dcb64SThomas Gleixner * broadcast handler, which did not run yet,
910989dcb64SThomas Gleixner * will invoke the cpu local handler.
911989dcb64SThomas Gleixner *
912989dcb64SThomas Gleixner * We cannot call the handler directly from
913989dcb64SThomas Gleixner * here, because we might be in a NOHZ phase
914989dcb64SThomas Gleixner * and we did not go through the irq_enter()
915989dcb64SThomas Gleixner * nohz fixups.
916989dcb64SThomas Gleixner */
917989dcb64SThomas Gleixner now = ktime_get();
9182456e855SThomas Gleixner if (dev->next_event <= now) {
919989dcb64SThomas Gleixner cpumask_set_cpu(cpu, tick_broadcast_force_mask);
920989dcb64SThomas Gleixner goto out;
921989dcb64SThomas Gleixner }
922989dcb64SThomas Gleixner /*
923989dcb64SThomas Gleixner * We got woken by something else. Reprogram
924989dcb64SThomas Gleixner * the cpu local timer device.
925989dcb64SThomas Gleixner */
92679bf2bb3SThomas Gleixner tick_program_event(dev->next_event, 1);
92779bf2bb3SThomas Gleixner }
92879bf2bb3SThomas Gleixner }
92926517f3eSThomas Gleixner out:
9301fe5d5c3SThomas Gleixner raw_spin_unlock(&tick_broadcast_lock);
931da7e6f45SPreeti U Murthy return ret;
93279bf2bb3SThomas Gleixner }
93379bf2bb3SThomas Gleixner
tick_oneshot_wakeup_control(enum tick_broadcast_state state,struct tick_device * td,int cpu)934ea5c7f1bSWill Deacon static int tick_oneshot_wakeup_control(enum tick_broadcast_state state,
935ea5c7f1bSWill Deacon struct tick_device *td,
936ea5c7f1bSWill Deacon int cpu)
937ea5c7f1bSWill Deacon {
938ea5c7f1bSWill Deacon struct clock_event_device *dev, *wd;
939ea5c7f1bSWill Deacon
940ea5c7f1bSWill Deacon dev = td->evtdev;
941ea5c7f1bSWill Deacon if (td->mode != TICKDEV_MODE_ONESHOT)
942ea5c7f1bSWill Deacon return -EINVAL;
943ea5c7f1bSWill Deacon
944ea5c7f1bSWill Deacon wd = tick_get_oneshot_wakeup_device(cpu);
945ea5c7f1bSWill Deacon if (!wd)
946ea5c7f1bSWill Deacon return -ENODEV;
947ea5c7f1bSWill Deacon
948ea5c7f1bSWill Deacon switch (state) {
949ea5c7f1bSWill Deacon case TICK_BROADCAST_ENTER:
950ea5c7f1bSWill Deacon clockevents_switch_state(dev, CLOCK_EVT_STATE_ONESHOT_STOPPED);
951ea5c7f1bSWill Deacon clockevents_switch_state(wd, CLOCK_EVT_STATE_ONESHOT);
952ea5c7f1bSWill Deacon clockevents_program_event(wd, dev->next_event, 1);
953ea5c7f1bSWill Deacon break;
954ea5c7f1bSWill Deacon case TICK_BROADCAST_EXIT:
955ea5c7f1bSWill Deacon /* We may have transitioned to oneshot mode while idle */
956ea5c7f1bSWill Deacon if (clockevent_get_state(wd) != CLOCK_EVT_STATE_ONESHOT)
957ea5c7f1bSWill Deacon return -ENODEV;
958ea5c7f1bSWill Deacon }
959ea5c7f1bSWill Deacon
960ea5c7f1bSWill Deacon return 0;
961ea5c7f1bSWill Deacon }
962ea5c7f1bSWill Deacon
__tick_broadcast_oneshot_control(enum tick_broadcast_state state)963e5007c28SWill Deacon int __tick_broadcast_oneshot_control(enum tick_broadcast_state state)
964e5007c28SWill Deacon {
965e5007c28SWill Deacon struct tick_device *td = this_cpu_ptr(&tick_cpu_device);
966e5007c28SWill Deacon int cpu = smp_processor_id();
967e5007c28SWill Deacon
968ea5c7f1bSWill Deacon if (!tick_oneshot_wakeup_control(state, td, cpu))
969ea5c7f1bSWill Deacon return 0;
970ea5c7f1bSWill Deacon
971e5007c28SWill Deacon if (tick_broadcast_device.evtdev)
972e5007c28SWill Deacon return ___tick_broadcast_oneshot_control(state, td, cpu);
973e5007c28SWill Deacon
974e5007c28SWill Deacon /*
975ea5c7f1bSWill Deacon * If there is no broadcast or wakeup device, tell the caller not
976e5007c28SWill Deacon * to go into deep idle.
977e5007c28SWill Deacon */
978e5007c28SWill Deacon return -EBUSY;
979e5007c28SWill Deacon }
980e5007c28SWill Deacon
9815590a536SThomas Gleixner /*
9825590a536SThomas Gleixner * Reset the one shot broadcast for a cpu
9835590a536SThomas Gleixner *
9845590a536SThomas Gleixner * Called with tick_broadcast_lock held
9855590a536SThomas Gleixner */
tick_broadcast_clear_oneshot(int cpu)9865590a536SThomas Gleixner static void tick_broadcast_clear_oneshot(int cpu)
9875590a536SThomas Gleixner {
988b352bc1cSThomas Gleixner cpumask_clear_cpu(cpu, tick_broadcast_oneshot_mask);
989dd5fd9b9SThomas Gleixner cpumask_clear_cpu(cpu, tick_broadcast_pending_mask);
9905590a536SThomas Gleixner }
9915590a536SThomas Gleixner
tick_broadcast_init_next_event(struct cpumask * mask,ktime_t expires)9926b954823SRusty Russell static void tick_broadcast_init_next_event(struct cpumask *mask,
9936b954823SRusty Russell ktime_t expires)
9947300711eSThomas Gleixner {
9957300711eSThomas Gleixner struct tick_device *td;
9967300711eSThomas Gleixner int cpu;
9977300711eSThomas Gleixner
9985db0e1e9SRusty Russell for_each_cpu(cpu, mask) {
9997300711eSThomas Gleixner td = &per_cpu(tick_cpu_device, cpu);
10007300711eSThomas Gleixner if (td->evtdev)
10017300711eSThomas Gleixner td->evtdev->next_event = expires;
10027300711eSThomas Gleixner }
10037300711eSThomas Gleixner }
10047300711eSThomas Gleixner
tick_get_next_period(void)1005f73f64d5SThomas Gleixner static inline ktime_t tick_get_next_period(void)
1006f73f64d5SThomas Gleixner {
1007f73f64d5SThomas Gleixner ktime_t next;
1008f73f64d5SThomas Gleixner
1009f73f64d5SThomas Gleixner /*
1010f73f64d5SThomas Gleixner * Protect against concurrent updates (store /load tearing on
1011f73f64d5SThomas Gleixner * 32bit). It does not matter if the time is already in the
1012f73f64d5SThomas Gleixner * past. The broadcast device which is about to be programmed will
1013f73f64d5SThomas Gleixner * fire in any case.
1014f73f64d5SThomas Gleixner */
1015f73f64d5SThomas Gleixner raw_spin_lock(&jiffies_lock);
1016f73f64d5SThomas Gleixner next = tick_next_period;
1017f73f64d5SThomas Gleixner raw_spin_unlock(&jiffies_lock);
1018f73f64d5SThomas Gleixner return next;
1019f73f64d5SThomas Gleixner }
1020f73f64d5SThomas Gleixner
102179bf2bb3SThomas Gleixner /**
10228dce39c2SLi Zefan * tick_broadcast_setup_oneshot - setup the broadcast device
102379bf2bb3SThomas Gleixner */
tick_broadcast_setup_oneshot(struct clock_event_device * bc,bool from_periodic)1024f9d36cf4SThomas Gleixner static void tick_broadcast_setup_oneshot(struct clock_event_device *bc,
1025f9d36cf4SThomas Gleixner bool from_periodic)
102679bf2bb3SThomas Gleixner {
102707f4beb0SThomas Gleixner int cpu = smp_processor_id();
1028f9d36cf4SThomas Gleixner ktime_t nexttick = 0;
102907f4beb0SThomas Gleixner
1030c1a9eeb9SThomas Gleixner if (!bc)
1031c1a9eeb9SThomas Gleixner return;
1032c1a9eeb9SThomas Gleixner
10337300711eSThomas Gleixner /*
1034f9d36cf4SThomas Gleixner * When the broadcast device was switched to oneshot by the first
1035f9d36cf4SThomas Gleixner * CPU handling the NOHZ change, the other CPUs will reach this
1036f9d36cf4SThomas Gleixner * code via hrtimer_run_queues() -> tick_check_oneshot_change()
1037f9d36cf4SThomas Gleixner * too. Set up the broadcast device only once!
10387300711eSThomas Gleixner */
1039f9d36cf4SThomas Gleixner if (bc->event_handler == tick_handle_oneshot_broadcast) {
104007f4beb0SThomas Gleixner /*
1041f9d36cf4SThomas Gleixner * The CPU which switched from periodic to oneshot mode
1042f9d36cf4SThomas Gleixner * set the broadcast oneshot bit for all other CPUs which
1043f9d36cf4SThomas Gleixner * are in the general (periodic) broadcast mask to ensure
1044f9d36cf4SThomas Gleixner * that CPUs which wait for the periodic broadcast are
1045f9d36cf4SThomas Gleixner * woken up.
1046f9d36cf4SThomas Gleixner *
1047f9d36cf4SThomas Gleixner * Clear the bit for the local CPU as the set bit would
1048f9d36cf4SThomas Gleixner * prevent the first tick_broadcast_enter() after this CPU
1049f9d36cf4SThomas Gleixner * switched to oneshot state to program the broadcast
1050f9d36cf4SThomas Gleixner * device.
1051f9d36cf4SThomas Gleixner *
1052f9d36cf4SThomas Gleixner * This code can also be reached via tick_broadcast_control(),
1053f9d36cf4SThomas Gleixner * but this cannot avoid the tick_broadcast_clear_oneshot()
1054f9d36cf4SThomas Gleixner * as that would break the periodic to oneshot transition of
1055f9d36cf4SThomas Gleixner * secondary CPUs. But that's harmless as the below only
1056f9d36cf4SThomas Gleixner * clears already cleared bits.
105707f4beb0SThomas Gleixner */
105807f4beb0SThomas Gleixner tick_broadcast_clear_oneshot(cpu);
1059f9d36cf4SThomas Gleixner return;
106079bf2bb3SThomas Gleixner }
1061f9d36cf4SThomas Gleixner
1062f9d36cf4SThomas Gleixner
1063f9d36cf4SThomas Gleixner bc->event_handler = tick_handle_oneshot_broadcast;
1064f9d36cf4SThomas Gleixner bc->next_event = KTIME_MAX;
1065f9d36cf4SThomas Gleixner
1066f9d36cf4SThomas Gleixner /*
1067f9d36cf4SThomas Gleixner * When the tick mode is switched from periodic to oneshot it must
1068f9d36cf4SThomas Gleixner * be ensured that CPUs which are waiting for periodic broadcast
1069f9d36cf4SThomas Gleixner * get their wake-up at the next tick. This is achieved by ORing
1070f9d36cf4SThomas Gleixner * tick_broadcast_mask into tick_broadcast_oneshot_mask.
1071f9d36cf4SThomas Gleixner *
1072f9d36cf4SThomas Gleixner * For other callers, e.g. broadcast device replacement,
1073f9d36cf4SThomas Gleixner * tick_broadcast_oneshot_mask must not be touched as this would
1074f9d36cf4SThomas Gleixner * set bits for CPUs which are already NOHZ, but not idle. Their
1075f9d36cf4SThomas Gleixner * next tick_broadcast_enter() would observe the bit set and fail
1076f9d36cf4SThomas Gleixner * to update the expiry time and the broadcast event device.
1077f9d36cf4SThomas Gleixner */
1078f9d36cf4SThomas Gleixner if (from_periodic) {
1079f9d36cf4SThomas Gleixner cpumask_copy(tmpmask, tick_broadcast_mask);
1080f9d36cf4SThomas Gleixner /* Remove the local CPU as it is obviously not idle */
1081f9d36cf4SThomas Gleixner cpumask_clear_cpu(cpu, tmpmask);
1082f9d36cf4SThomas Gleixner cpumask_or(tick_broadcast_oneshot_mask, tick_broadcast_oneshot_mask, tmpmask);
1083f9d36cf4SThomas Gleixner
1084f9d36cf4SThomas Gleixner /*
1085f9d36cf4SThomas Gleixner * Ensure that the oneshot broadcast handler will wake the
1086f9d36cf4SThomas Gleixner * CPUs which are still waiting for periodic broadcast.
1087f9d36cf4SThomas Gleixner */
1088f9d36cf4SThomas Gleixner nexttick = tick_get_next_period();
1089f9d36cf4SThomas Gleixner tick_broadcast_init_next_event(tmpmask, nexttick);
1090f9d36cf4SThomas Gleixner
1091f9d36cf4SThomas Gleixner /*
1092f9d36cf4SThomas Gleixner * If the underlying broadcast clock event device is
1093f9d36cf4SThomas Gleixner * already in oneshot state, then there is nothing to do.
1094f9d36cf4SThomas Gleixner * The device was already armed for the next tick
1095f9d36cf4SThomas Gleixner * in tick_handle_broadcast_periodic()
1096f9d36cf4SThomas Gleixner */
1097f9d36cf4SThomas Gleixner if (clockevent_state_oneshot(bc))
1098f9d36cf4SThomas Gleixner return;
1099f9d36cf4SThomas Gleixner }
1100f9d36cf4SThomas Gleixner
1101f9d36cf4SThomas Gleixner /*
1102f9d36cf4SThomas Gleixner * When switching from periodic to oneshot mode arm the broadcast
1103f9d36cf4SThomas Gleixner * device for the next tick.
1104f9d36cf4SThomas Gleixner *
1105f9d36cf4SThomas Gleixner * If the broadcast device has been replaced in oneshot mode and
1106f9d36cf4SThomas Gleixner * the oneshot broadcast mask is not empty, then arm it to expire
1107f9d36cf4SThomas Gleixner * immediately in order to reevaluate the next expiring timer.
1108f9d36cf4SThomas Gleixner * @nexttick is 0 and therefore in the past which will cause the
1109f9d36cf4SThomas Gleixner * clockevent code to force an event.
1110f9d36cf4SThomas Gleixner *
1111f9d36cf4SThomas Gleixner * For both cases the programming can be avoided when the oneshot
1112f9d36cf4SThomas Gleixner * broadcast mask is empty.
1113f9d36cf4SThomas Gleixner *
1114f9d36cf4SThomas Gleixner * tick_broadcast_set_event() implicitly switches the broadcast
1115f9d36cf4SThomas Gleixner * device to oneshot state.
1116f9d36cf4SThomas Gleixner */
1117f9d36cf4SThomas Gleixner if (!cpumask_empty(tick_broadcast_oneshot_mask))
1118f9d36cf4SThomas Gleixner tick_broadcast_set_event(bc, cpu, nexttick);
11199c17bcdaSThomas Gleixner }
112079bf2bb3SThomas Gleixner
112179bf2bb3SThomas Gleixner /*
112279bf2bb3SThomas Gleixner * Select oneshot operating mode for the broadcast device
112379bf2bb3SThomas Gleixner */
tick_broadcast_switch_to_oneshot(void)112479bf2bb3SThomas Gleixner void tick_broadcast_switch_to_oneshot(void)
112579bf2bb3SThomas Gleixner {
112679bf2bb3SThomas Gleixner struct clock_event_device *bc;
1127f9d36cf4SThomas Gleixner enum tick_device_mode oldmode;
112879bf2bb3SThomas Gleixner unsigned long flags;
112979bf2bb3SThomas Gleixner
1130b5f91da0SThomas Gleixner raw_spin_lock_irqsave(&tick_broadcast_lock, flags);
1131fa4da365SSuresh Siddha
1132f9d36cf4SThomas Gleixner oldmode = tick_broadcast_device.mode;
1133fa4da365SSuresh Siddha tick_broadcast_device.mode = TICKDEV_MODE_ONESHOT;
113479bf2bb3SThomas Gleixner bc = tick_broadcast_device.evtdev;
113579bf2bb3SThomas Gleixner if (bc)
1136f9d36cf4SThomas Gleixner tick_broadcast_setup_oneshot(bc, oldmode == TICKDEV_MODE_PERIODIC);
113777b0d60cSSuresh Siddha
1138b5f91da0SThomas Gleixner raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags);
113979bf2bb3SThomas Gleixner }
114079bf2bb3SThomas Gleixner
1141a49b116dSThomas Gleixner #ifdef CONFIG_HOTPLUG_CPU
hotplug_cpu__broadcast_tick_pull(int deadcpu)1142a49b116dSThomas Gleixner void hotplug_cpu__broadcast_tick_pull(int deadcpu)
1143a49b116dSThomas Gleixner {
1144a49b116dSThomas Gleixner struct clock_event_device *bc;
1145a49b116dSThomas Gleixner unsigned long flags;
1146a49b116dSThomas Gleixner
1147a49b116dSThomas Gleixner raw_spin_lock_irqsave(&tick_broadcast_lock, flags);
1148a49b116dSThomas Gleixner bc = tick_broadcast_device.evtdev;
1149a49b116dSThomas Gleixner
1150a49b116dSThomas Gleixner if (bc && broadcast_needs_cpu(bc, deadcpu)) {
11513a58c590SYu Liao /*
11523a58c590SYu Liao * If the broadcast force bit of the current CPU is set,
11533a58c590SYu Liao * then the current CPU has not yet reprogrammed the local
11543a58c590SYu Liao * timer device to avoid a ping-pong race. See
11553a58c590SYu Liao * ___tick_broadcast_oneshot_control().
11563a58c590SYu Liao *
11573a58c590SYu Liao * If the broadcast device is hrtimer based then
11583a58c590SYu Liao * programming the broadcast event below does not have any
11593a58c590SYu Liao * effect because the local clockevent device is not
11603a58c590SYu Liao * running and not programmed because the broadcast event
11613a58c590SYu Liao * is not earlier than the pending event of the local clock
11623a58c590SYu Liao * event device. As a consequence all CPUs waiting for a
11633a58c590SYu Liao * broadcast event are stuck forever.
11643a58c590SYu Liao *
11653a58c590SYu Liao * Detect this condition and reprogram the cpu local timer
11663a58c590SYu Liao * device to avoid the starvation.
11673a58c590SYu Liao */
11683a58c590SYu Liao if (tick_check_broadcast_expired()) {
1169*b9d60493SThomas Gleixner struct tick_device *td = this_cpu_ptr(&tick_cpu_device);
1170*b9d60493SThomas Gleixner
11713a58c590SYu Liao cpumask_clear_cpu(smp_processor_id(), tick_broadcast_force_mask);
11723a58c590SYu Liao tick_program_event(td->evtdev->next_event, 1);
11733a58c590SYu Liao }
11743a58c590SYu Liao
1175a49b116dSThomas Gleixner /* This moves the broadcast assignment to this CPU: */
1176a49b116dSThomas Gleixner clockevents_program_event(bc, bc->next_event, 1);
1177a49b116dSThomas Gleixner }
1178a49b116dSThomas Gleixner raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags);
1179a49b116dSThomas Gleixner }
118079bf2bb3SThomas Gleixner
118179bf2bb3SThomas Gleixner /*
11821b72d432SThomas Gleixner * Remove a dying CPU from broadcasting
118379bf2bb3SThomas Gleixner */
tick_broadcast_oneshot_offline(unsigned int cpu)11841b72d432SThomas Gleixner static void tick_broadcast_oneshot_offline(unsigned int cpu)
118579bf2bb3SThomas Gleixner {
1186c94a8537SWill Deacon if (tick_get_oneshot_wakeup_device(cpu))
1187c94a8537SWill Deacon tick_set_oneshot_wakeup_device(NULL, cpu);
1188c94a8537SWill Deacon
118931d9b393SThomas Gleixner /*
1190c9b5a266SThomas Gleixner * Clear the broadcast masks for the dead cpu, but do not stop
1191c9b5a266SThomas Gleixner * the broadcast device!
119231d9b393SThomas Gleixner */
1193b352bc1cSThomas Gleixner cpumask_clear_cpu(cpu, tick_broadcast_oneshot_mask);
1194c9b5a266SThomas Gleixner cpumask_clear_cpu(cpu, tick_broadcast_pending_mask);
1195c9b5a266SThomas Gleixner cpumask_clear_cpu(cpu, tick_broadcast_force_mask);
119679bf2bb3SThomas Gleixner }
1197a49b116dSThomas Gleixner #endif
119879bf2bb3SThomas Gleixner
119927ce4cb4SThomas Gleixner /*
120027ce4cb4SThomas Gleixner * Check, whether the broadcast device is in one shot mode
120127ce4cb4SThomas Gleixner */
tick_broadcast_oneshot_active(void)120227ce4cb4SThomas Gleixner int tick_broadcast_oneshot_active(void)
120327ce4cb4SThomas Gleixner {
120427ce4cb4SThomas Gleixner return tick_broadcast_device.mode == TICKDEV_MODE_ONESHOT;
120527ce4cb4SThomas Gleixner }
120627ce4cb4SThomas Gleixner
12073a142a06SThomas Gleixner /*
12083a142a06SThomas Gleixner * Check whether the broadcast device supports oneshot.
12093a142a06SThomas Gleixner */
tick_broadcast_oneshot_available(void)12103a142a06SThomas Gleixner bool tick_broadcast_oneshot_available(void)
12113a142a06SThomas Gleixner {
12123a142a06SThomas Gleixner struct clock_event_device *bc = tick_broadcast_device.evtdev;
12133a142a06SThomas Gleixner
12143a142a06SThomas Gleixner return bc ? bc->features & CLOCK_EVT_FEAT_ONESHOT : false;
12153a142a06SThomas Gleixner }
12163a142a06SThomas Gleixner
1217f32dd117SThomas Gleixner #else
__tick_broadcast_oneshot_control(enum tick_broadcast_state state)1218f32dd117SThomas Gleixner int __tick_broadcast_oneshot_control(enum tick_broadcast_state state)
1219f32dd117SThomas Gleixner {
1220f32dd117SThomas Gleixner struct clock_event_device *bc = tick_broadcast_device.evtdev;
1221f32dd117SThomas Gleixner
1222f32dd117SThomas Gleixner if (!bc || (bc->features & CLOCK_EVT_FEAT_HRTIMER))
1223f32dd117SThomas Gleixner return -EBUSY;
1224f32dd117SThomas Gleixner
1225f32dd117SThomas Gleixner return 0;
1226f32dd117SThomas Gleixner }
122779bf2bb3SThomas Gleixner #endif
1228b352bc1cSThomas Gleixner
tick_broadcast_init(void)1229b352bc1cSThomas Gleixner void __init tick_broadcast_init(void)
1230b352bc1cSThomas Gleixner {
1231fbd44a60SThomas Gleixner zalloc_cpumask_var(&tick_broadcast_mask, GFP_NOWAIT);
123207bd1172SThomas Gleixner zalloc_cpumask_var(&tick_broadcast_on, GFP_NOWAIT);
1233fbd44a60SThomas Gleixner zalloc_cpumask_var(&tmpmask, GFP_NOWAIT);
1234b352bc1cSThomas Gleixner #ifdef CONFIG_TICK_ONESHOT
1235fbd44a60SThomas Gleixner zalloc_cpumask_var(&tick_broadcast_oneshot_mask, GFP_NOWAIT);
1236fbd44a60SThomas Gleixner zalloc_cpumask_var(&tick_broadcast_pending_mask, GFP_NOWAIT);
1237fbd44a60SThomas Gleixner zalloc_cpumask_var(&tick_broadcast_force_mask, GFP_NOWAIT);
1238b352bc1cSThomas Gleixner #endif
1239b352bc1cSThomas Gleixner }
1240