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
....@@ -80,14 +85,17 @@
8085 static void tick_periodic(int cpu)
8186 {
8287 if (tick_do_timer_cpu == cpu) {
83
- write_seqlock(&jiffies_lock);
88
+ raw_spin_lock(&jiffies_lock);
89
+ write_seqcount_begin(&jiffies_seq);
8490
8591 /* Keep track of the next tick event */
8692 tick_next_period = ktime_add(tick_next_period, tick_period);
8793
8894 do_timer(1);
89
- write_sequnlock(&jiffies_lock);
95
+ write_seqcount_end(&jiffies_seq);
96
+ raw_spin_unlock(&jiffies_lock);
9097 update_wall_time();
98
+ trace_android_vh_jiffies_update(NULL);
9199 }
92100
93101 update_process_times(user_mode(get_irq_regs()));
....@@ -154,13 +162,13 @@
154162 !tick_broadcast_oneshot_active()) {
155163 clockevents_switch_state(dev, CLOCK_EVT_STATE_PERIODIC);
156164 } else {
157
- unsigned long seq;
165
+ unsigned int seq;
158166 ktime_t next;
159167
160168 do {
161
- seq = read_seqbegin(&jiffies_lock);
169
+ seq = read_seqcount_begin(&jiffies_seq);
162170 next = tick_next_period;
163
- } while (read_seqretry(&jiffies_lock, seq));
171
+ } while (read_seqcount_retry(&jiffies_seq, seq));
164172
165173 clockevents_switch_state(dev, CLOCK_EVT_STATE_ONESHOT);
166174
....@@ -171,6 +179,26 @@
171179 }
172180 }
173181 }
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
174202
175203 /*
176204 * Setup the tick device
....@@ -191,12 +219,26 @@
191219 * this cpu:
192220 */
193221 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;
222
+ tick_do_timer_cpu = cpu;
223
+
198224 tick_next_period = ktime_get();
199225 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
200242 }
201243
202244 /*
....@@ -338,7 +380,7 @@
338380 /*
339381 * Can the new device be used as a broadcast device ?
340382 */
341
- tick_install_broadcast_device(newdev);
383
+ tick_install_broadcast_device(newdev, cpu);
342384 }
343385
344386 /**