hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/kernel/time/tick-common.c
....@@ -1,15 +1,11 @@
1
+// SPDX-License-Identifier: GPL-2.0
12 /*
2
- * linux/kernel/time/tick-common.c
3
- *
43 * This file contains the base functions to manage periodic tick
54 * related events.
65 *
76 * Copyright(C) 2005-2006, Thomas Gleixner <tglx@linutronix.de>
87 * Copyright(C) 2005-2007, Red Hat, Inc., Ingo Molnar
98 * Copyright(C) 2006-2007, Timesys Corp., Thomas Gleixner
10
- *
11
- * This code is licenced under the GPL version 2. For details see
12
- * kernel-base/COPYING.
139 */
1410 #include <linux/cpu.h>
1511 #include <linux/err.h>
....@@ -21,6 +17,7 @@
2117 #include <linux/sched.h>
2218 #include <linux/module.h>
2319 #include <trace/events/power.h>
20
+#include <trace/hooks/sched.h>
2421
2522 #include <asm/irq_regs.h>
2623
....@@ -34,7 +31,6 @@
3431 * Tick next event: keeps track of the tick time
3532 */
3633 ktime_t tick_next_period;
37
-ktime_t tick_period;
3834
3935 /*
4036 * tick_do_timer_cpu is a timer core internal variable which holds the CPU NR
....@@ -51,6 +47,14 @@
5147 * procedure also covers cpu hotplug.
5248 */
5349 int tick_do_timer_cpu __read_mostly = TICK_DO_TIMER_BOOT;
50
+#ifdef CONFIG_NO_HZ_FULL
51
+/*
52
+ * tick_do_timer_boot_cpu indicates the boot CPU temporarily owns
53
+ * tick_do_timer_cpu and it should be taken over by an eligible secondary
54
+ * when one comes online.
55
+ */
56
+static int tick_do_timer_boot_cpu __read_mostly = -1;
57
+#endif
5458
5559 /*
5660 * Debugging: see timer_list.c
....@@ -80,14 +84,17 @@
8084 static void tick_periodic(int cpu)
8185 {
8286 if (tick_do_timer_cpu == cpu) {
83
- write_seqlock(&jiffies_lock);
87
+ raw_spin_lock(&jiffies_lock);
88
+ write_seqcount_begin(&jiffies_seq);
8489
8590 /* Keep track of the next tick event */
86
- tick_next_period = ktime_add(tick_next_period, tick_period);
91
+ tick_next_period = ktime_add_ns(tick_next_period, TICK_NSEC);
8792
8893 do_timer(1);
89
- write_sequnlock(&jiffies_lock);
94
+ write_seqcount_end(&jiffies_seq);
95
+ raw_spin_unlock(&jiffies_lock);
9096 update_wall_time();
97
+ trace_android_vh_jiffies_update(NULL);
9198 }
9299
93100 update_process_times(user_mode(get_irq_regs()));
....@@ -121,7 +128,7 @@
121128 * Setup the next period for devices, which do not have
122129 * periodic mode:
123130 */
124
- next = ktime_add(next, tick_period);
131
+ next = ktime_add_ns(next, TICK_NSEC);
125132
126133 if (!clockevents_program_event(dev, next, false))
127134 return;
....@@ -154,23 +161,43 @@
154161 !tick_broadcast_oneshot_active()) {
155162 clockevents_switch_state(dev, CLOCK_EVT_STATE_PERIODIC);
156163 } else {
157
- unsigned long seq;
164
+ unsigned int seq;
158165 ktime_t next;
159166
160167 do {
161
- seq = read_seqbegin(&jiffies_lock);
168
+ seq = read_seqcount_begin(&jiffies_seq);
162169 next = tick_next_period;
163
- } while (read_seqretry(&jiffies_lock, seq));
170
+ } while (read_seqcount_retry(&jiffies_seq, seq));
164171
165172 clockevents_switch_state(dev, CLOCK_EVT_STATE_ONESHOT);
166173
167174 for (;;) {
168175 if (!clockevents_program_event(dev, next, false))
169176 return;
170
- next = ktime_add(next, tick_period);
177
+ next = ktime_add_ns(next, TICK_NSEC);
171178 }
172179 }
173180 }
181
+
182
+#ifdef CONFIG_NO_HZ_FULL
183
+static void giveup_do_timer(void *info)
184
+{
185
+ int cpu = *(unsigned int *)info;
186
+
187
+ WARN_ON(tick_do_timer_cpu != smp_processor_id());
188
+
189
+ tick_do_timer_cpu = cpu;
190
+}
191
+
192
+static void tick_take_do_timer_from_boot(void)
193
+{
194
+ int cpu = smp_processor_id();
195
+ int from = tick_do_timer_boot_cpu;
196
+
197
+ if (from >= 0 && from != cpu)
198
+ smp_call_function_single(from, giveup_do_timer, &cpu, 1);
199
+}
200
+#endif
174201
175202 /*
176203 * Setup the tick device
....@@ -191,12 +218,24 @@
191218 * this cpu:
192219 */
193220 if (tick_do_timer_cpu == TICK_DO_TIMER_BOOT) {
194
- if (!tick_nohz_full_cpu(cpu))
195
- tick_do_timer_cpu = cpu;
196
- else
197
- tick_do_timer_cpu = TICK_DO_TIMER_NONE;
221
+ tick_do_timer_cpu = cpu;
198222 tick_next_period = ktime_get();
199
- tick_period = NSEC_PER_SEC / HZ;
223
+#ifdef CONFIG_NO_HZ_FULL
224
+ /*
225
+ * The boot CPU may be nohz_full, in which case set
226
+ * tick_do_timer_boot_cpu so the first housekeeping
227
+ * secondary that comes up will take do_timer from
228
+ * us.
229
+ */
230
+ if (tick_nohz_full_cpu(cpu))
231
+ tick_do_timer_boot_cpu = cpu;
232
+
233
+ } else if (tick_do_timer_boot_cpu != -1 &&
234
+ !tick_nohz_full_cpu(cpu)) {
235
+ tick_take_do_timer_from_boot();
236
+ tick_do_timer_boot_cpu = -1;
237
+ WARN_ON(tick_do_timer_cpu != cpu);
238
+#endif
200239 }
201240
202241 /*
....@@ -338,7 +377,7 @@
338377 /*
339378 * Can the new device be used as a broadcast device ?
340379 */
341
- tick_install_broadcast_device(newdev);
380
+ tick_install_broadcast_device(newdev, cpu);
342381 }
343382
344383 /**