diff options
Diffstat (limited to 'features/clear_warn_once/clear_warn_once-bind-a-timer-to-written-reset-value.patch')
-rw-r--r-- | features/clear_warn_once/clear_warn_once-bind-a-timer-to-written-reset-value.patch | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/features/clear_warn_once/clear_warn_once-bind-a-timer-to-written-reset-value.patch b/features/clear_warn_once/clear_warn_once-bind-a-timer-to-written-reset-value.patch new file mode 100644 index 00000000..63053deb --- /dev/null +++ b/features/clear_warn_once/clear_warn_once-bind-a-timer-to-written-reset-value.patch @@ -0,0 +1,104 @@ +From fbda05a6df0125f733e0e28a3e0ae60bb6765d51 Mon Sep 17 00:00:00 2001 +From: Paul Gortmaker <paul.gortmaker@windriver.com> +Date: Wed, 16 Dec 2020 12:22:57 -0500 +Subject: [PATCH 2/3] clear_warn_once: bind a timer to written reset value + +Existing documentation has a write of "1" to clear/reset all the +WARN_ONCE and similar to the as-booted state, so they can possibly +be re-triggered again during debugging/testing. + +But having them auto-reset once a day, or once a week, might shed +valuable information to a sysadmin on what the system is doing while +trying to debug an issue. + +Here we extend the existing debugfs variable to bind a timer to the +written value N, so that it will reset every N minutes, for N>1. +Writing a zero will clear any previously set timer value. + +The pre-existing behaviour of writing N=1 will do a one-shot clear. + +Link: https://lore.kernel.org/r/20201126063029.2030-1-paul.gortmaker@windriver.com +Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> +Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com> +--- + .../admin-guide/clearing-warn-once.rst | 9 ++++++ + kernel/panic.c | 32 +++++++++++++++++++ + 2 files changed, 41 insertions(+) + +diff --git a/Documentation/admin-guide/clearing-warn-once.rst b/Documentation/admin-guide/clearing-warn-once.rst +index 211fd926cf00..8d058bbc0859 100644 +--- a/Documentation/admin-guide/clearing-warn-once.rst ++++ b/Documentation/admin-guide/clearing-warn-once.rst +@@ -7,3 +7,12 @@ echo 1 > /sys/kernel/debug/clear_warn_once + + clears the state and allows the warnings to print once again. + This can be useful after test suite runs to reproduce problems. ++ ++Values greater than one set a timer for a periodic state reset; e.g. ++ ++echo 60 > /sys/kernel/debug/clear_warn_once ++ ++will establish an hourly state reset, effectively turning WARN_ONCE ++into a long period rate-limited warning. ++ ++Writing a value of zero (or one) will remove any previously set timer. +diff --git a/kernel/panic.c b/kernel/panic.c +index 53088219d7df..e3a462e39062 100644 +--- a/kernel/panic.c ++++ b/kernel/panic.c +@@ -636,6 +636,7 @@ EXPORT_SYMBOL(__warn_printk); + /* Support resetting WARN*_ONCE state */ + + static u64 clear_warn_once; ++static bool warn_timer_active; + + static void do_clear_warn_once(void) + { +@@ -643,6 +644,14 @@ static void do_clear_warn_once(void) + memset(__start_once, 0, __end_once - __start_once); + } + ++static void timer_warn_once(struct timer_list *timer) ++{ ++ do_clear_warn_once(); ++ timer->expires = jiffies + clear_warn_once * HZ * 60; ++ add_timer(timer); ++} ++static DEFINE_TIMER(warn_reset_timer, timer_warn_once); ++ + static int warn_once_get(void *data, u64 *val) + { + *val = clear_warn_once; +@@ -653,6 +662,29 @@ static int warn_once_set(void *data, u64 val) + { + clear_warn_once = val; + ++ if (val > 1) { /* set/reset new timer */ ++ unsigned long expires = jiffies + val * HZ * 60; ++ ++ if (warn_timer_active) { ++ mod_timer(&warn_reset_timer, expires); ++ } else { ++ warn_timer_active = 1; ++ warn_reset_timer.expires = expires; ++ add_timer(&warn_reset_timer); ++ } ++ return 0; ++ } ++ ++ if (warn_timer_active) { ++ del_timer_sync(&warn_reset_timer); ++ warn_timer_active = 0; ++ } ++ clear_warn_once = 0; ++ ++ if (val == 0) /* cleared timer, we are done */ ++ return 0; ++ ++ /* Getting here means val == 1 ---> so clear existing data */ + do_clear_warn_once(); + return 0; + } +-- +2.19.1 + |