| .. | .. | 
|---|
 | 1 | +// SPDX-License-Identifier: GPL-2.0  | 
|---|
| 1 | 2 |  /* | 
|---|
| 2 |  | - * linux/kernel/time/tick-common.c  | 
|---|
| 3 |  | - *  | 
|---|
| 4 | 3 |   * This file contains the base functions to manage periodic tick | 
|---|
| 5 | 4 |   * related events. | 
|---|
| 6 | 5 |   * | 
|---|
| 7 | 6 |   * Copyright(C) 2005-2006, Thomas Gleixner <tglx@linutronix.de> | 
|---|
| 8 | 7 |   * Copyright(C) 2005-2007, Red Hat, Inc., Ingo Molnar | 
|---|
| 9 | 8 |   * 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.  | 
|---|
| 13 | 9 |   */ | 
|---|
| 14 | 10 |  #include <linux/cpu.h> | 
|---|
| 15 | 11 |  #include <linux/err.h> | 
|---|
| .. | .. | 
|---|
| 21 | 17 |  #include <linux/sched.h> | 
|---|
| 22 | 18 |  #include <linux/module.h> | 
|---|
| 23 | 19 |  #include <trace/events/power.h> | 
|---|
 | 20 | +#include <trace/hooks/sched.h>  | 
|---|
| 24 | 21 |   | 
|---|
| 25 | 22 |  #include <asm/irq_regs.h> | 
|---|
| 26 | 23 |   | 
|---|
| .. | .. | 
|---|
| 51 | 48 |   *    procedure also covers cpu hotplug. | 
|---|
| 52 | 49 |   */ | 
|---|
| 53 | 50 |  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  | 
|---|
| 54 | 59 |   | 
|---|
| 55 | 60 |  /* | 
|---|
| 56 | 61 |   * Debugging: see timer_list.c | 
|---|
| .. | .. | 
|---|
| 80 | 85 |  static void tick_periodic(int cpu) | 
|---|
| 81 | 86 |  { | 
|---|
| 82 | 87 |  	if (tick_do_timer_cpu == cpu) { | 
|---|
| 83 |  | -		write_seqlock(&jiffies_lock);  | 
|---|
 | 88 | +		raw_spin_lock(&jiffies_lock);  | 
|---|
 | 89 | +		write_seqcount_begin(&jiffies_seq);  | 
|---|
| 84 | 90 |   | 
|---|
| 85 | 91 |  		/* Keep track of the next tick event */ | 
|---|
| 86 | 92 |  		tick_next_period = ktime_add(tick_next_period, tick_period); | 
|---|
| 87 | 93 |   | 
|---|
| 88 | 94 |  		do_timer(1); | 
|---|
| 89 |  | -		write_sequnlock(&jiffies_lock);  | 
|---|
 | 95 | +		write_seqcount_end(&jiffies_seq);  | 
|---|
 | 96 | +		raw_spin_unlock(&jiffies_lock);  | 
|---|
| 90 | 97 |  		update_wall_time(); | 
|---|
 | 98 | +		trace_android_vh_jiffies_update(NULL);  | 
|---|
| 91 | 99 |  	} | 
|---|
| 92 | 100 |   | 
|---|
| 93 | 101 |  	update_process_times(user_mode(get_irq_regs())); | 
|---|
| .. | .. | 
|---|
| 154 | 162 |  	    !tick_broadcast_oneshot_active()) { | 
|---|
| 155 | 163 |  		clockevents_switch_state(dev, CLOCK_EVT_STATE_PERIODIC); | 
|---|
| 156 | 164 |  	} else { | 
|---|
| 157 |  | -		unsigned long seq;  | 
|---|
 | 165 | +		unsigned int seq;  | 
|---|
| 158 | 166 |  		ktime_t next; | 
|---|
| 159 | 167 |   | 
|---|
| 160 | 168 |  		do { | 
|---|
| 161 |  | -			seq = read_seqbegin(&jiffies_lock);  | 
|---|
 | 169 | +			seq = read_seqcount_begin(&jiffies_seq);  | 
|---|
| 162 | 170 |  			next = tick_next_period; | 
|---|
| 163 |  | -		} while (read_seqretry(&jiffies_lock, seq));  | 
|---|
 | 171 | +		} while (read_seqcount_retry(&jiffies_seq, seq));  | 
|---|
| 164 | 172 |   | 
|---|
| 165 | 173 |  		clockevents_switch_state(dev, CLOCK_EVT_STATE_ONESHOT); | 
|---|
| 166 | 174 |   | 
|---|
| .. | .. | 
|---|
| 171 | 179 |  		} | 
|---|
| 172 | 180 |  	} | 
|---|
| 173 | 181 |  } | 
|---|
 | 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  | 
|---|
| 174 | 202 |   | 
|---|
| 175 | 203 |  /* | 
|---|
| 176 | 204 |   * Setup the tick device | 
|---|
| .. | .. | 
|---|
| 191 | 219 |  		 * this cpu: | 
|---|
| 192 | 220 |  		 */ | 
|---|
| 193 | 221 |  		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 | +  | 
|---|
| 198 | 224 |  			tick_next_period = ktime_get(); | 
|---|
| 199 | 225 |  			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  | 
|---|
| 200 | 242 |  		} | 
|---|
| 201 | 243 |   | 
|---|
| 202 | 244 |  		/* | 
|---|
| .. | .. | 
|---|
| 338 | 380 |  	/* | 
|---|
| 339 | 381 |  	 * Can the new device be used as a broadcast device ? | 
|---|
| 340 | 382 |  	 */ | 
|---|
| 341 |  | -	tick_install_broadcast_device(newdev);  | 
|---|
 | 383 | +	tick_install_broadcast_device(newdev, cpu);  | 
|---|
| 342 | 384 |  } | 
|---|
| 343 | 385 |   | 
|---|
| 344 | 386 |  /** | 
|---|