hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
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
....@@ -51,6 +48,14 @@
5148 * procedure also covers cpu hotplug.
5249 */
5350 int tick_do_timer_cpu __read_mostly = TICK_DO_TIMER_BOOT;
51
+#ifdef CONFIG_NO_HZ_FULL
52
+/*
53
+ * tick_do_timer_boot_cpu indicates the boot CPU temporarily owns
54
+ * tick_do_timer_cpu and it should be taken over by an eligible secondary
55
+ * when one comes online.
56
+ */
57
+static int tick_do_timer_boot_cpu __read_mostly = -1;
58
+#endif
5459
5560 /*
5661 * Debugging: see timer_list.c
....@@ -90,6 +95,7 @@
9095 write_seqcount_end(&jiffies_seq);
9196 raw_spin_unlock(&jiffies_lock);
9297 update_wall_time();
98
+ trace_android_vh_jiffies_update(NULL);
9399 }
94100
95101 update_process_times(user_mode(get_irq_regs()));
....@@ -156,7 +162,7 @@
156162 !tick_broadcast_oneshot_active()) {
157163 clockevents_switch_state(dev, CLOCK_EVT_STATE_PERIODIC);
158164 } else {
159
- unsigned long seq;
165
+ unsigned int seq;
160166 ktime_t next;
161167
162168 do {
....@@ -173,6 +179,26 @@
173179 }
174180 }
175181 }
182
+
183
+#ifdef CONFIG_NO_HZ_FULL
184
+static void giveup_do_timer(void *info)
185
+{
186
+ int cpu = *(unsigned int *)info;
187
+
188
+ WARN_ON(tick_do_timer_cpu != smp_processor_id());
189
+
190
+ tick_do_timer_cpu = cpu;
191
+}
192
+
193
+static void tick_take_do_timer_from_boot(void)
194
+{
195
+ int cpu = smp_processor_id();
196
+ int from = tick_do_timer_boot_cpu;
197
+
198
+ if (from >= 0 && from != cpu)
199
+ smp_call_function_single(from, giveup_do_timer, &cpu, 1);
200
+}
201
+#endif
176202
177203 /*
178204 * Setup the tick device
....@@ -193,12 +219,26 @@
193219 * this cpu:
194220 */
195221 if (tick_do_timer_cpu == TICK_DO_TIMER_BOOT) {
196
- if (!tick_nohz_full_cpu(cpu))
197
- tick_do_timer_cpu = cpu;
198
- else
199
- tick_do_timer_cpu = TICK_DO_TIMER_NONE;
222
+ tick_do_timer_cpu = cpu;
223
+
200224 tick_next_period = ktime_get();
201225 tick_period = NSEC_PER_SEC / HZ;
226
+#ifdef CONFIG_NO_HZ_FULL
227
+ /*
228
+ * The boot CPU may be nohz_full, in which case set
229
+ * tick_do_timer_boot_cpu so the first housekeeping
230
+ * secondary that comes up will take do_timer from
231
+ * us.
232
+ */
233
+ if (tick_nohz_full_cpu(cpu))
234
+ tick_do_timer_boot_cpu = cpu;
235
+
236
+ } else if (tick_do_timer_boot_cpu != -1 &&
237
+ !tick_nohz_full_cpu(cpu)) {
238
+ tick_take_do_timer_from_boot();
239
+ tick_do_timer_boot_cpu = -1;
240
+ WARN_ON(tick_do_timer_cpu != cpu);
241
+#endif
202242 }
203243
204244 /*
....@@ -340,7 +380,7 @@
340380 /*
341381 * Can the new device be used as a broadcast device ?
342382 */
343
- tick_install_broadcast_device(newdev);
383
+ tick_install_broadcast_device(newdev, cpu);
344384 }
345385
346386 /**