Skip to content

Commit 60bc47b

Browse files
Yicong Yangwilldeacon
authored andcommitted
watchdog/perf: Provide function for adjusting the event period
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 hardlockup_detector_perf_adjust_period() to allowing adjust the event period. Then architecture can update with more accurate period if cpufreq is initialized. Reviewed-by: Douglas Anderson <dianders@chromium.org> Signed-off-by: Yicong Yang <yangyicong@hisilicon.com> Link: https://lore.kernel.org/r/20250701110214.27242-2-yangyicong@huawei.com Signed-off-by: Will Deacon <will@kernel.org>
1 parent 19272b3 commit 60bc47b

2 files changed

Lines changed: 24 additions & 0 deletions

File tree

include/linux/nmi.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,12 @@ void watchdog_hardlockup_check(unsigned int cpu, struct pt_regs *regs);
103103
extern void hardlockup_detector_perf_stop(void);
104104
extern void hardlockup_detector_perf_restart(void);
105105
extern void hardlockup_config_perf_event(const char *str);
106+
extern void hardlockup_detector_perf_adjust_period(u64 period);
106107
#else
107108
static inline void hardlockup_detector_perf_stop(void) { }
108109
static inline void hardlockup_detector_perf_restart(void) { }
109110
static inline void hardlockup_config_perf_event(const char *str) { }
111+
static inline void hardlockup_detector_perf_adjust_period(u64 period) { }
110112
#endif
111113

112114
void watchdog_hardlockup_stop(void);

kernel/watchdog_perf.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,28 @@ void watchdog_hardlockup_disable(unsigned int cpu)
186186
}
187187
}
188188

189+
/**
190+
* hardlockup_detector_perf_adjust_period - Adjust the event period due
191+
* to current cpu frequency change
192+
* @period: The target period to be set
193+
*/
194+
void hardlockup_detector_perf_adjust_period(u64 period)
195+
{
196+
struct perf_event *event = this_cpu_read(watchdog_ev);
197+
198+
if (!(watchdog_enabled & WATCHDOG_HARDLOCKUP_ENABLED))
199+
return;
200+
201+
if (!event)
202+
return;
203+
204+
if (event->attr.sample_period == period)
205+
return;
206+
207+
if (perf_event_period(event, period))
208+
pr_err("failed to change period to %llu\n", period);
209+
}
210+
189211
/**
190212
* hardlockup_detector_perf_stop - Globally stop watchdog events
191213
*

0 commit comments

Comments
 (0)