2020-12-20 03:46:29

by Xiaoming Ni

[permalink] [raw]
Subject: [PATCH v2 0/4] panic: Add new API in_panic_state()

For some features (such as hang_task, ledtrig-activity, ledtrig-heartbeat)
different processing logics need to be performed based on whether the
current system is in panic state:
1: Register hook for panic_notifier_list.
2. Assign a value to the global variable in the hook function.
3. Determine whether the system is in panic state based on the
global variable and perform different processing.
Duplicate code snippets exist, and the timing judgment is relatively lag.
Therefore, consider extracting the new API: bool in_panic_state(void).

----------------

v2: Rename api to in_panic_state as recommended by Pavel Machek, Tetsuo
Handa, Randy Dunlap.

v1: https://lore.kernel.org/lkml/[email protected]/
API name: is_being_panic
----------------

Xiaoming Ni (4):
panic: Add new API in_panic_state()
hung_task: Replace "did_panic" with in_panic_state()
leds:trigger:ledtrig-activity Replace "panic_detected" with
in_panic_state()
leds:trigger:ledtrig-heartbeat: Replace "panic_heartbeats" with
in_panic_state()

drivers/leds/trigger/ledtrig-activity.c | 19 +------------------
drivers/leds/trigger/ledtrig-heartbeat.c | 19 +------------------
include/linux/kernel.h | 1 +
kernel/hung_task.c | 17 +----------------
kernel/panic.c | 6 ++++++
5 files changed, 10 insertions(+), 52 deletions(-)

--
2.27.0


2020-12-20 03:46:34

by Xiaoming Ni

[permalink] [raw]
Subject: [PATCH v2 1/4] panic: Add new API in_panic_state()

For some features (such as hang_task, ledtrig-activity, ledtrig-heartbeat)
different processing logics need to be performed based on whether the
current system is in panic state:
1: Register hook for panic_notifier_list.
2. Assign a value to the global variable in the hook function.
3. Determine whether the system is in panic state based on the
global variable and perform different processing.
Duplicate code snippets exist, and the timing judgment is relatively lag.
Therefore, consider extracting the new API: bool in_panic_state(void).

Signed-off-by: Xiaoming Ni <[email protected]>
---
include/linux/kernel.h | 1 +
kernel/panic.c | 6 ++++++
2 files changed, 7 insertions(+)

diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index f7902d8c1048..c9a9078157b6 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -167,6 +167,7 @@ void __might_fault(const char *file, int line);
static inline void might_fault(void) { }
#endif

+extern bool in_panic_state(void);
extern struct atomic_notifier_head panic_notifier_list;
extern long (*panic_blink)(int state);
__printf(1, 2)
diff --git a/kernel/panic.c b/kernel/panic.c
index 332736a72a58..351627883a04 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -125,6 +125,12 @@ void __weak crash_smp_send_stop(void)

atomic_t panic_cpu = ATOMIC_INIT(PANIC_CPU_INVALID);

+bool in_panic_state(void)
+{
+ return (atomic_read(&panic_cpu) != PANIC_CPU_INVALID);
+}
+EXPORT_SYMBOL(in_panic_state);
+
/*
* A variant of panic() called from NMI context. We return if we've already
* panicked on this CPU. If another CPU already panicked, loop in
--
2.27.0

2020-12-20 03:46:40

by Xiaoming Ni

[permalink] [raw]
Subject: [PATCH v2 3/4] leds:trigger:ledtrig-activity Replace "panic_detected" with in_panic_state()

Replace the global variable "panic_detected" with in_panic_state()

Signed-off-by: Xiaoming Ni <[email protected]>
---
drivers/leds/trigger/ledtrig-activity.c | 19 +------------------
1 file changed, 1 insertion(+), 18 deletions(-)

diff --git a/drivers/leds/trigger/ledtrig-activity.c b/drivers/leds/trigger/ledtrig-activity.c
index 14ba7faaed9e..9675c9348516 100644
--- a/drivers/leds/trigger/ledtrig-activity.c
+++ b/drivers/leds/trigger/ledtrig-activity.c
@@ -17,8 +17,6 @@
#include <linux/timer.h>
#include "../leds.h"

-static int panic_detected;
-
struct activity_data {
struct timer_list timer;
struct led_classdev *led_cdev;
@@ -47,7 +45,7 @@ static void led_activity_function(struct timer_list *t)
if (test_and_clear_bit(LED_BLINK_BRIGHTNESS_CHANGE, &led_cdev->work_flags))
led_cdev->blink_brightness = led_cdev->new_blink_brightness;

- if (unlikely(panic_detected)) {
+ if (unlikely(in_panic_state())) {
/* full brightness in case of panic */
led_set_brightness_nosleep(led_cdev, led_cdev->blink_brightness);
return;
@@ -226,28 +224,15 @@ static int activity_reboot_notifier(struct notifier_block *nb,
return NOTIFY_DONE;
}

-static int activity_panic_notifier(struct notifier_block *nb,
- unsigned long code, void *unused)
-{
- panic_detected = 1;
- return NOTIFY_DONE;
-}
-
static struct notifier_block activity_reboot_nb = {
.notifier_call = activity_reboot_notifier,
};

-static struct notifier_block activity_panic_nb = {
- .notifier_call = activity_panic_notifier,
-};
-
static int __init activity_init(void)
{
int rc = led_trigger_register(&activity_led_trigger);

if (!rc) {
- atomic_notifier_chain_register(&panic_notifier_list,
- &activity_panic_nb);
register_reboot_notifier(&activity_reboot_nb);
}
return rc;
@@ -256,8 +241,6 @@ static int __init activity_init(void)
static void __exit activity_exit(void)
{
unregister_reboot_notifier(&activity_reboot_nb);
- atomic_notifier_chain_unregister(&panic_notifier_list,
- &activity_panic_nb);
led_trigger_unregister(&activity_led_trigger);
}

--
2.27.0

2020-12-20 03:47:14

by Xiaoming Ni

[permalink] [raw]
Subject: [PATCH v2 2/4] hung_task: Replace "did_panic" with in_panic_state()

Replace the global variable "did_panic" with in_panic_state()

Signed-off-by: Xiaoming Ni <[email protected]>
---
kernel/hung_task.c | 17 +----------------
1 file changed, 1 insertion(+), 16 deletions(-)

diff --git a/kernel/hung_task.c b/kernel/hung_task.c
index bb2e3e15c84c..2747cd6dd35e 100644
--- a/kernel/hung_task.c
+++ b/kernel/hung_task.c
@@ -50,7 +50,6 @@ unsigned long __read_mostly sysctl_hung_task_check_interval_secs;

int __read_mostly sysctl_hung_task_warnings = 10;

-static int __read_mostly did_panic;
static bool hung_task_show_lock;
static bool hung_task_call_panic;
static bool hung_task_show_all_bt;
@@ -72,18 +71,6 @@ unsigned int __read_mostly sysctl_hung_task_all_cpu_backtrace;
unsigned int __read_mostly sysctl_hung_task_panic =
CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE;

-static int
-hung_task_panic(struct notifier_block *this, unsigned long event, void *ptr)
-{
- did_panic = 1;
-
- return NOTIFY_DONE;
-}
-
-static struct notifier_block panic_block = {
- .notifier_call = hung_task_panic,
-};
-
static void check_hung_task(struct task_struct *t, unsigned long timeout)
{
unsigned long switch_count = t->nvcsw + t->nivcsw;
@@ -223,7 +210,7 @@ static void check_hung_uninterruptible_tasks(unsigned long timeout)
* If the system crashed already then all bets are off,
* do not report extra hung tasks:
*/
- if (test_taint(TAINT_DIE) || did_panic)
+ if (test_taint(TAINT_DIE) || unlikely(in_panic_state()))
return;

hung_task_show_lock = false;
@@ -347,8 +334,6 @@ static int watchdog(void *dummy)

static int __init hung_task_init(void)
{
- atomic_notifier_chain_register(&panic_notifier_list, &panic_block);
-
/* Disable hung task detector on suspend */
pm_notifier(hungtask_pm_notify, 0);

--
2.27.0

2020-12-20 03:47:29

by Xiaoming Ni

[permalink] [raw]
Subject: [PATCH v2 4/4] leds:trigger:ledtrig-heartbeat: Replace "panic_heartbeats" with in_panic_state()

Replace the global variable "panic_heartbeats" with in_panic_state()

Signed-off-by: Xiaoming Ni <[email protected]>
---
drivers/leds/trigger/ledtrig-heartbeat.c | 19 +------------------
1 file changed, 1 insertion(+), 18 deletions(-)

diff --git a/drivers/leds/trigger/ledtrig-heartbeat.c b/drivers/leds/trigger/ledtrig-heartbeat.c
index 36b6709afe9f..f24d64cf0a62 100644
--- a/drivers/leds/trigger/ledtrig-heartbeat.c
+++ b/drivers/leds/trigger/ledtrig-heartbeat.c
@@ -19,8 +19,6 @@
#include <linux/reboot.h>
#include "../leds.h"

-static int panic_heartbeats;
-
struct heartbeat_trig_data {
struct led_classdev *led_cdev;
unsigned int phase;
@@ -39,7 +37,7 @@ static void led_heartbeat_function(struct timer_list *t)

led_cdev = heartbeat_data->led_cdev;

- if (unlikely(panic_heartbeats)) {
+ if (unlikely(in_panic_state())) {
led_set_brightness_nosleep(led_cdev, LED_OFF);
return;
}
@@ -169,28 +167,15 @@ static int heartbeat_reboot_notifier(struct notifier_block *nb,
return NOTIFY_DONE;
}

-static int heartbeat_panic_notifier(struct notifier_block *nb,
- unsigned long code, void *unused)
-{
- panic_heartbeats = 1;
- return NOTIFY_DONE;
-}
-
static struct notifier_block heartbeat_reboot_nb = {
.notifier_call = heartbeat_reboot_notifier,
};

-static struct notifier_block heartbeat_panic_nb = {
- .notifier_call = heartbeat_panic_notifier,
-};
-
static int __init heartbeat_trig_init(void)
{
int rc = led_trigger_register(&heartbeat_led_trigger);

if (!rc) {
- atomic_notifier_chain_register(&panic_notifier_list,
- &heartbeat_panic_nb);
register_reboot_notifier(&heartbeat_reboot_nb);
}
return rc;
@@ -199,8 +184,6 @@ static int __init heartbeat_trig_init(void)
static void __exit heartbeat_trig_exit(void)
{
unregister_reboot_notifier(&heartbeat_reboot_nb);
- atomic_notifier_chain_unregister(&panic_notifier_list,
- &heartbeat_panic_nb);
led_trigger_unregister(&heartbeat_led_trigger);
}

--
2.27.0