0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062 notrace unsigned long long __weak sched_clock(void)
0063 {
0064 return (unsigned long long)(jiffies - INITIAL_JIFFIES)
0065 * (NSEC_PER_SEC / HZ);
0066 }
0067 EXPORT_SYMBOL_GPL(sched_clock);
0068
0069 static DEFINE_STATIC_KEY_FALSE(sched_clock_running);
0070
0071 #ifdef CONFIG_HAVE_UNSTABLE_SCHED_CLOCK
0072
0073
0074
0075
0076
0077
0078
0079 static DEFINE_STATIC_KEY_FALSE(__sched_clock_stable);
0080 static int __sched_clock_stable_early = 1;
0081
0082
0083
0084
0085 __read_mostly u64 __sched_clock_offset;
0086 static __read_mostly u64 __gtod_offset;
0087
0088 struct sched_clock_data {
0089 u64 tick_raw;
0090 u64 tick_gtod;
0091 u64 clock;
0092 };
0093
0094 static DEFINE_PER_CPU_SHARED_ALIGNED(struct sched_clock_data, sched_clock_data);
0095
0096 notrace static inline struct sched_clock_data *this_scd(void)
0097 {
0098 return this_cpu_ptr(&sched_clock_data);
0099 }
0100
0101 notrace static inline struct sched_clock_data *cpu_sdc(int cpu)
0102 {
0103 return &per_cpu(sched_clock_data, cpu);
0104 }
0105
0106 notrace int sched_clock_stable(void)
0107 {
0108 return static_branch_likely(&__sched_clock_stable);
0109 }
0110
0111 notrace static void __scd_stamp(struct sched_clock_data *scd)
0112 {
0113 scd->tick_gtod = ktime_get_ns();
0114 scd->tick_raw = sched_clock();
0115 }
0116
0117 notrace static void __set_sched_clock_stable(void)
0118 {
0119 struct sched_clock_data *scd;
0120
0121
0122
0123
0124
0125 local_irq_disable();
0126 scd = this_scd();
0127
0128
0129
0130 __sched_clock_offset = (scd->tick_gtod + __gtod_offset) - (scd->tick_raw);
0131 local_irq_enable();
0132
0133 printk(KERN_INFO "sched_clock: Marking stable (%lld, %lld)->(%lld, %lld)\n",
0134 scd->tick_gtod, __gtod_offset,
0135 scd->tick_raw, __sched_clock_offset);
0136
0137 static_branch_enable(&__sched_clock_stable);
0138 tick_dep_clear(TICK_DEP_BIT_CLOCK_UNSTABLE);
0139 }
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152 notrace static void __sched_clock_work(struct work_struct *work)
0153 {
0154 struct sched_clock_data *scd;
0155 int cpu;
0156
0157
0158 preempt_disable();
0159 scd = this_scd();
0160 __scd_stamp(scd);
0161 scd->clock = scd->tick_gtod + __gtod_offset;
0162 preempt_enable();
0163
0164
0165 for_each_possible_cpu(cpu)
0166 per_cpu(sched_clock_data, cpu) = *scd;
0167
0168 printk(KERN_WARNING "TSC found unstable after boot, most likely due to broken BIOS. Use 'tsc=unstable'.\n");
0169 printk(KERN_INFO "sched_clock: Marking unstable (%lld, %lld)<-(%lld, %lld)\n",
0170 scd->tick_gtod, __gtod_offset,
0171 scd->tick_raw, __sched_clock_offset);
0172
0173 static_branch_disable(&__sched_clock_stable);
0174 }
0175
0176 static DECLARE_WORK(sched_clock_work, __sched_clock_work);
0177
0178 notrace static void __clear_sched_clock_stable(void)
0179 {
0180 if (!sched_clock_stable())
0181 return;
0182
0183 tick_dep_set(TICK_DEP_BIT_CLOCK_UNSTABLE);
0184 schedule_work(&sched_clock_work);
0185 }
0186
0187 notrace void clear_sched_clock_stable(void)
0188 {
0189 __sched_clock_stable_early = 0;
0190
0191 smp_mb();
0192
0193 if (static_key_count(&sched_clock_running.key) == 2)
0194 __clear_sched_clock_stable();
0195 }
0196
0197 notrace static void __sched_clock_gtod_offset(void)
0198 {
0199 struct sched_clock_data *scd = this_scd();
0200
0201 __scd_stamp(scd);
0202 __gtod_offset = (scd->tick_raw + __sched_clock_offset) - scd->tick_gtod;
0203 }
0204
0205 void __init sched_clock_init(void)
0206 {
0207
0208
0209
0210
0211
0212
0213
0214 local_irq_disable();
0215 __sched_clock_gtod_offset();
0216 local_irq_enable();
0217
0218 static_branch_inc(&sched_clock_running);
0219 }
0220
0221
0222
0223
0224 static int __init sched_clock_init_late(void)
0225 {
0226 static_branch_inc(&sched_clock_running);
0227
0228
0229
0230
0231
0232
0233
0234 smp_mb();
0235
0236 if (__sched_clock_stable_early)
0237 __set_sched_clock_stable();
0238
0239 return 0;
0240 }
0241 late_initcall(sched_clock_init_late);
0242
0243
0244
0245
0246
0247 notrace static inline u64 wrap_min(u64 x, u64 y)
0248 {
0249 return (s64)(x - y) < 0 ? x : y;
0250 }
0251
0252 notrace static inline u64 wrap_max(u64 x, u64 y)
0253 {
0254 return (s64)(x - y) > 0 ? x : y;
0255 }
0256
0257
0258
0259
0260
0261
0262
0263 notrace static u64 sched_clock_local(struct sched_clock_data *scd)
0264 {
0265 u64 now, clock, old_clock, min_clock, max_clock, gtod;
0266 s64 delta;
0267
0268 again:
0269 now = sched_clock();
0270 delta = now - scd->tick_raw;
0271 if (unlikely(delta < 0))
0272 delta = 0;
0273
0274 old_clock = scd->clock;
0275
0276
0277
0278
0279
0280
0281
0282 gtod = scd->tick_gtod + __gtod_offset;
0283 clock = gtod + delta;
0284 min_clock = wrap_max(gtod, old_clock);
0285 max_clock = wrap_max(old_clock, gtod + TICK_NSEC);
0286
0287 clock = wrap_max(clock, min_clock);
0288 clock = wrap_min(clock, max_clock);
0289
0290 if (!try_cmpxchg64(&scd->clock, &old_clock, clock))
0291 goto again;
0292
0293 return clock;
0294 }
0295
0296 notrace static u64 sched_clock_remote(struct sched_clock_data *scd)
0297 {
0298 struct sched_clock_data *my_scd = this_scd();
0299 u64 this_clock, remote_clock;
0300 u64 *ptr, old_val, val;
0301
0302 #if BITS_PER_LONG != 64
0303 again:
0304
0305
0306
0307
0308
0309
0310
0311
0312
0313
0314
0315 this_clock = sched_clock_local(my_scd);
0316
0317
0318
0319
0320
0321 remote_clock = cmpxchg64(&scd->clock, 0, 0);
0322 #else
0323
0324
0325
0326
0327 sched_clock_local(my_scd);
0328 again:
0329 this_clock = my_scd->clock;
0330 remote_clock = scd->clock;
0331 #endif
0332
0333
0334
0335
0336
0337
0338
0339 if (likely((s64)(remote_clock - this_clock) < 0)) {
0340 ptr = &scd->clock;
0341 old_val = remote_clock;
0342 val = this_clock;
0343 } else {
0344
0345
0346
0347 ptr = &my_scd->clock;
0348 old_val = this_clock;
0349 val = remote_clock;
0350 }
0351
0352 if (!try_cmpxchg64(ptr, &old_val, val))
0353 goto again;
0354
0355 return val;
0356 }
0357
0358
0359
0360
0361
0362
0363 notrace u64 sched_clock_cpu(int cpu)
0364 {
0365 struct sched_clock_data *scd;
0366 u64 clock;
0367
0368 if (sched_clock_stable())
0369 return sched_clock() + __sched_clock_offset;
0370
0371 if (!static_branch_likely(&sched_clock_running))
0372 return sched_clock();
0373
0374 preempt_disable_notrace();
0375 scd = cpu_sdc(cpu);
0376
0377 if (cpu != smp_processor_id())
0378 clock = sched_clock_remote(scd);
0379 else
0380 clock = sched_clock_local(scd);
0381 preempt_enable_notrace();
0382
0383 return clock;
0384 }
0385 EXPORT_SYMBOL_GPL(sched_clock_cpu);
0386
0387 notrace void sched_clock_tick(void)
0388 {
0389 struct sched_clock_data *scd;
0390
0391 if (sched_clock_stable())
0392 return;
0393
0394 if (!static_branch_likely(&sched_clock_running))
0395 return;
0396
0397 lockdep_assert_irqs_disabled();
0398
0399 scd = this_scd();
0400 __scd_stamp(scd);
0401 sched_clock_local(scd);
0402 }
0403
0404 notrace void sched_clock_tick_stable(void)
0405 {
0406 if (!sched_clock_stable())
0407 return;
0408
0409
0410
0411
0412
0413
0414
0415
0416 local_irq_disable();
0417 __sched_clock_gtod_offset();
0418 local_irq_enable();
0419 }
0420
0421
0422
0423
0424 notrace void sched_clock_idle_sleep_event(void)
0425 {
0426 sched_clock_cpu(smp_processor_id());
0427 }
0428 EXPORT_SYMBOL_GPL(sched_clock_idle_sleep_event);
0429
0430
0431
0432
0433 notrace void sched_clock_idle_wakeup_event(void)
0434 {
0435 unsigned long flags;
0436
0437 if (sched_clock_stable())
0438 return;
0439
0440 if (unlikely(timekeeping_suspended))
0441 return;
0442
0443 local_irq_save(flags);
0444 sched_clock_tick();
0445 local_irq_restore(flags);
0446 }
0447 EXPORT_SYMBOL_GPL(sched_clock_idle_wakeup_event);
0448
0449 #else
0450
0451 void __init sched_clock_init(void)
0452 {
0453 static_branch_inc(&sched_clock_running);
0454 local_irq_disable();
0455 generic_sched_clock_init();
0456 local_irq_enable();
0457 }
0458
0459 notrace u64 sched_clock_cpu(int cpu)
0460 {
0461 if (!static_branch_likely(&sched_clock_running))
0462 return 0;
0463
0464 return sched_clock();
0465 }
0466
0467 #endif
0468
0469
0470
0471
0472
0473
0474
0475
0476
0477 notrace u64 __weak running_clock(void)
0478 {
0479 return local_clock();
0480 }