[PATCH 1/2] watchdog/perf: Provide function for adjusting the event period
Yicong Yang
yangyicong at huawei.com
Thu Mar 6 18:18:10 PST 2025
From: Yicong Yang <yangyicong at hisilicon.com>
Architecture's using perf events for hard lockup detection needs to
convert the watchdog_thresh to the event's period, some architecture
for example arm64 perform this conversion using the CPU's maximum
frequency which will be acquired by cpufreq. However by the time
the lockup detector's initialized the cpufreq driver may not be
initialized, thus launch a watchdog with inaccurate period. Provide
a function dhardlockup_detector_perf_adjust_period() to allowing
adjust the event period. Then architecture can update with more
accurate period if cpufreq is initialized.
Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
---
include/linux/nmi.h | 2 ++
kernel/watchdog_perf.c | 21 +++++++++++++++++++++
2 files changed, 23 insertions(+)
diff --git a/include/linux/nmi.h b/include/linux/nmi.h
index a8dfb38c9bb6..2200ce481439 100644
--- a/include/linux/nmi.h
+++ b/include/linux/nmi.h
@@ -106,11 +106,13 @@ extern void hardlockup_detector_perf_stop(void);
extern void hardlockup_detector_perf_restart(void);
extern void hardlockup_detector_perf_cleanup(void);
extern void hardlockup_config_perf_event(const char *str);
+extern void hardlockup_detector_perf_adjust_period(int cpu, u64 period);
#else
static inline void hardlockup_detector_perf_stop(void) { }
static inline void hardlockup_detector_perf_restart(void) { }
static inline void hardlockup_detector_perf_cleanup(void) { }
static inline void hardlockup_config_perf_event(const char *str) { }
+static inline void hardlockup_detector_perf_adjust_period(int cpu, u64 period) { }
#endif
void watchdog_hardlockup_stop(void);
diff --git a/kernel/watchdog_perf.c b/kernel/watchdog_perf.c
index 59c1d86a73a2..bc00985d1f69 100644
--- a/kernel/watchdog_perf.c
+++ b/kernel/watchdog_perf.c
@@ -211,6 +211,27 @@ void hardlockup_detector_perf_cleanup(void)
cpumask_clear(&dead_events_mask);
}
+/**
+ * hardlockup_detector_perf_adjust_period - Adjust the events period due
+ * to cpu frequency change
+ */
+void hardlockup_detector_perf_adjust_period(int cpu, u64 period)
+{
+ struct perf_event *event = per_cpu(watchdog_ev, cpu);
+
+ if (!(watchdog_enabled & WATCHDOG_HARDLOCKUP_ENABLED))
+ return;
+
+ if (!event)
+ return;
+
+ if (event->attr.sample_period == period)
+ return;
+
+ if (perf_event_period(event, period))
+ pr_err("failed to change period to %llu\n", period);
+}
+
/**
* hardlockup_detector_perf_stop - Globally stop watchdog events
*
--
2.24.0
More information about the linux-arm-kernel
mailing list