Message ID | 20230829194200.1901988-2-festevam@gmail.com (mailing list archive) |
---|---|
State | Changes Requested, archived |
Headers | show |
Series | [v5,1/3] dt-bindings: thermal-zones: Document critical-action | expand |
On Tue, Aug 29, 2023 at 9:42 PM Fabio Estevam <festevam@gmail.com> wrote: > > From: Fabio Estevam <festevam@denx.de> > > Introduce hw_protection_reboot() to trigger an emergency reboot. > > It is a counterpart of hw_protection_shutdown() with the difference > that it will force a reboot instead of shutdown. > > The motivation for doing this is to allow the thermal subystem > to trigger a reboot when the temperature reaches the critical > temperature. > > Signed-off-by: Fabio Estevam <festevam@denx.de> > --- > Changes since v4: > - None > > include/linux/reboot.h | 1 + > kernel/reboot.c | 34 ++++++++++++++++++++++++++++++++++ > 2 files changed, 35 insertions(+) > > diff --git a/include/linux/reboot.h b/include/linux/reboot.h > index 2b6bb593be5b..4a319bc24f6a 100644 > --- a/include/linux/reboot.h > +++ b/include/linux/reboot.h > @@ -174,6 +174,7 @@ void ctrl_alt_del(void); > > extern void orderly_poweroff(bool force); > extern void orderly_reboot(void); > +void hw_protection_reboot(const char *reason, int ms_until_forced); > void hw_protection_shutdown(const char *reason, int ms_until_forced); > > /* > diff --git a/kernel/reboot.c b/kernel/reboot.c > index 3bba88c7ffc6..05333ae8bc6b 100644 > --- a/kernel/reboot.c > +++ b/kernel/reboot.c > @@ -952,6 +952,40 @@ static void hw_failure_emergency_poweroff(int poweroff_delay_ms) > msecs_to_jiffies(poweroff_delay_ms)); > } > > +/** > + * hw_protection_reboot - Trigger an emergency system reboot > + * > + * @reason: Reason of emergency reboot to be printed. > + * @ms_until_forced: Time to wait for orderly reboot before tiggering a > + * forced reboot. Negative value disables the forced > + * reboot. > + * > + * Initiate an emergency system reboot in order to protect hardware from > + * further damage. Usage examples include a thermal protection. > + * > + * NOTE: The request is ignored if protection reboot is already pending even > + * if the previous request has given a large timeout for forced reboot. > + * Can be called from any context. > + */ > +void hw_protection_reboot(const char *reason, int ms_until_forced) Some code and kerneldoc comment duplication could be avoided by changing hw_protection_shutdown() definition to take an additional argument specifying the final action to carry out, so there would be void __hw_protection_shutdown(const char *reason, int ms_until_forced, bool reboot) { ... if (reboot) orderly_reboot(); else orderly_poweroff(true); } and both hw_protection_shutdown() and hw_protection_reboot() can be defined as static inline wrappers around this. > +{ > + static atomic_t allow_proceed = ATOMIC_INIT(1); > + > + pr_emerg("HARDWARE PROTECTION reboot (%s)\n", reason); > + > + /* Reboot should be initiated only once. */ > + if (!atomic_dec_and_test(&allow_proceed)) > + return; > + > + /* > + * Queue a backup emergency reboot in the event of > + * orderly_reboot failure > + */ > + hw_failure_emergency_poweroff(ms_until_forced); > + orderly_reboot(); > +} > +EXPORT_SYMBOL_GPL(hw_protection_reboot); > + > /** > * hw_protection_shutdown - Trigger an emergency system poweroff > * > -- > 2.34.1 >
diff --git a/include/linux/reboot.h b/include/linux/reboot.h index 2b6bb593be5b..4a319bc24f6a 100644 --- a/include/linux/reboot.h +++ b/include/linux/reboot.h @@ -174,6 +174,7 @@ void ctrl_alt_del(void); extern void orderly_poweroff(bool force); extern void orderly_reboot(void); +void hw_protection_reboot(const char *reason, int ms_until_forced); void hw_protection_shutdown(const char *reason, int ms_until_forced); /* diff --git a/kernel/reboot.c b/kernel/reboot.c index 3bba88c7ffc6..05333ae8bc6b 100644 --- a/kernel/reboot.c +++ b/kernel/reboot.c @@ -952,6 +952,40 @@ static void hw_failure_emergency_poweroff(int poweroff_delay_ms) msecs_to_jiffies(poweroff_delay_ms)); } +/** + * hw_protection_reboot - Trigger an emergency system reboot + * + * @reason: Reason of emergency reboot to be printed. + * @ms_until_forced: Time to wait for orderly reboot before tiggering a + * forced reboot. Negative value disables the forced + * reboot. + * + * Initiate an emergency system reboot in order to protect hardware from + * further damage. Usage examples include a thermal protection. + * + * NOTE: The request is ignored if protection reboot is already pending even + * if the previous request has given a large timeout for forced reboot. + * Can be called from any context. + */ +void hw_protection_reboot(const char *reason, int ms_until_forced) +{ + static atomic_t allow_proceed = ATOMIC_INIT(1); + + pr_emerg("HARDWARE PROTECTION reboot (%s)\n", reason); + + /* Reboot should be initiated only once. */ + if (!atomic_dec_and_test(&allow_proceed)) + return; + + /* + * Queue a backup emergency reboot in the event of + * orderly_reboot failure + */ + hw_failure_emergency_poweroff(ms_until_forced); + orderly_reboot(); +} +EXPORT_SYMBOL_GPL(hw_protection_reboot); + /** * hw_protection_shutdown - Trigger an emergency system poweroff *