aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul E. McKenney <paulmck@kernel.org>2021-07-28 16:04:35 -0700
committerPaul E. McKenney <paulmck@kernel.org>2021-08-12 09:40:30 -0700
commit97c274758ba2517477cb43ad2c49af82ea18572d (patch)
tree2dc4ac9b637bdfaad37510a816afeb91c5dd0b52
parent901203a9b6c041cfa84bc5803aaa9a3b0c1d9188 (diff)
downloadlinux-rcu-97c274758ba2517477cb43ad2c49af82ea18572d.tar.gz
EXP cpu: Make cpu_hp_check_delay() return true when detecting an anomaly
Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
-rw-r--r--include/linux/cpu.h4
-rw-r--r--kernel/cpu.c17
2 files changed, 14 insertions, 7 deletions
diff --git a/include/linux/cpu.h b/include/linux/cpu.h
index 2cdd1afd03504..93b9a28ea2bcd 100644
--- a/include/linux/cpu.h
+++ b/include/linux/cpu.h
@@ -130,7 +130,7 @@ int cpu_device_down(struct device *dev);
extern void smp_shutdown_nonboot_cpus(unsigned int primary_cpu);
extern void cpu_hp_start_now(void);
extern void cpu_hp_stop_now(void);
-extern void cpu_hp_check_delay(const char *s, const void *func);
+extern bool cpu_hp_check_delay(const char *s, const void *func);
#else /* CONFIG_HOTPLUG_CPU */
@@ -146,7 +146,7 @@ static inline int remove_cpu(unsigned int cpu) { return -EPERM; }
static inline void smp_shutdown_nonboot_cpus(unsigned int primary_cpu) { }
static inline void cpu_hp_start_now(void) { }
static inline void cpu_hp_stop_now(void) { }
-static inline void cpu_hp_check_delay(const char *s, void *func) { }
+static inline bool cpu_hp_check_delay(const char *s, void *func) { return false; }
#endif /* !CONFIG_HOTPLUG_CPU */
/* Wrappers which go away once all code is converted */
diff --git a/kernel/cpu.c b/kernel/cpu.c
index b0112cd976e3e..6ae1c7544d5b4 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -154,21 +154,28 @@ void cpu_hp_stop_now(void)
smp_store_release(&cpu_hp_start_time_valid, false);
}
-void cpu_hp_check_delay(const char *s, const void *func)
+/* Return true if a time-delay anomaly was detected. */
+bool cpu_hp_check_delay(const char *s, const void *func)
{
+ bool ret = false;
u64 t, t1;
if (!smp_load_acquire(&cpu_hp_start_time_valid))
- return;
+ return false;
t = READ_ONCE(cpu_hp_start_time);
smp_mb();
if (!READ_ONCE(cpu_hp_start_time_valid))
- return;
+ return false;
t1 = ktime_get();
- if (WARN_ONCE(time_after64(t1, t + 100 * NSEC_PER_SEC), "%s %ps took %llu milliseconds\n", s, func, (t1 - t) / NSEC_PER_MSEC))
+ if (WARN_ONCE(time_after64(t1, t + 100 * NSEC_PER_SEC), "%s %ps took %llu milliseconds\n", s, func, (t1 - t) / NSEC_PER_MSEC)) {
WRITE_ONCE(cpu_hp_start_time, t1);
- if (WARN_ONCE(time_before64(t1, t - 25 * NSEC_PER_MSEC), "%s %ps clock went backwards %llu milliseconds\n", s, func, (t - t1) / NSEC_PER_MSEC))
+ ret = true;
+ }
+ if (WARN_ONCE(time_before64(t1, t - 25 * NSEC_PER_MSEC), "%s %ps clock went backwards %llu milliseconds\n", s, func, (t - t1) / NSEC_PER_MSEC)){
WRITE_ONCE(cpu_hp_start_time, t1);
+ ret = true;
+ }
+ return ret;
}
#endif /* #ifdef CONFIG_SMP */