Skip to content

Commit fb31fbe

Browse files
ahollerBryan Wu
authored and
Bryan Wu
committed
leds: heartbeat: fix bug on panic
With commit 49dca5a I introduced a bug (visible if CONFIG_PROVE_RCU is enabled) which occures when a panic has happened: [ 1526.520230] =============================== [ 1526.520230] [ INFO: suspicious RCU usage. ] [ 1526.520230] 3.5.0-rc1+ #12 Not tainted [ 1526.520230] ------------------------------- [ 1526.520230] /c/kernel-tests/mm/include/linux/rcupdate.h:436 Illegal context switch in RCU read-side critical section! [ 1526.520230] [ 1526.520230] other info that might help us debug this: [ 1526.520230] [ 1526.520230] [ 1526.520230] rcu_scheduler_active = 1, debug_locks = 0 [ 1526.520230] 3 locks held by net.agent/3279: [ 1526.520230] #0: (&mm->mmap_sem){++++++}, at: [<ffffffff82f85962>] do_page_fault+0x193/0x390 [ 1526.520230] #1: (panic_lock){+.+...}, at: [<ffffffff82ed2830>] panic+0x37/0x1d3 [ 1526.520230] #2: (rcu_read_lock){.+.+..}, at: [<ffffffff810b9b28>] rcu_lock_acquire+0x0/0x29 [ 1526.520230] [ 1526.520230] stack backtrace: [ 1526.520230] Pid: 3279, comm: net.agent Not tainted 3.5.0-rc1+ #12 [ 1526.520230] Call Trace: [ 1526.520230] [<ffffffff810e1570>] lockdep_rcu_suspicious+0x109/0x112 [ 1526.520230] [<ffffffff810bfe3a>] rcu_preempt_sleep_check+0x45/0x47 [ 1526.520230] [<ffffffff810bfe5a>] __might_sleep+0x1e/0x19a [ 1526.520230] [<ffffffff82f8010e>] down_write+0x26/0x81 [ 1526.520230] [<ffffffff8276a966>] led_trigger_unregister+0x1f/0x9c [ 1526.520230] [<ffffffff8276def5>] heartbeat_reboot_notifier+0x15/0x19 [ 1526.520230] [<ffffffff82f85bf5>] notifier_call_chain+0x96/0xcd [ 1526.520230] [<ffffffff82f85cba>] __atomic_notifier_call_chain+0x8e/0xff [ 1526.520230] [<ffffffff81094b7c>] ? kmsg_dump+0x37/0x1eb [ 1526.520230] [<ffffffff82f85d3f>] atomic_notifier_call_chain+0x14/0x16 [ 1526.520230] [<ffffffff82ed28e1>] panic+0xe8/0x1d3 [ 1526.520230] [<ffffffff811473e2>] out_of_memory+0x15d/0x1d3 So in case of a panic, now just turn of the LED. Other approaches like scheduling a work to unregister the trigger aren't working because there isn't much which still runs after a panic occured (except timers). Signed-off-by: Alexander Holler <[email protected]> Signed-off-by: Bryan Wu <[email protected]>
1 parent 9e85a6f commit fb31fbe

File tree

1 file changed

+15
-1
lines changed

1 file changed

+15
-1
lines changed

drivers/leds/ledtrig-heartbeat.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
#include <linux/reboot.h>
2222
#include "leds.h"
2323

24+
static int panic_heartbeats;
25+
2426
struct heartbeat_trig_data {
2527
unsigned int phase;
2628
unsigned int period;
@@ -34,6 +36,11 @@ static void led_heartbeat_function(unsigned long data)
3436
unsigned long brightness = LED_OFF;
3537
unsigned long delay = 0;
3638

39+
if (unlikely(panic_heartbeats)) {
40+
led_set_brightness(led_cdev, LED_OFF);
41+
return;
42+
}
43+
3744
/* acts like an actual heart beat -- ie thump-thump-pause... */
3845
switch (heartbeat_data->phase) {
3946
case 0:
@@ -111,12 +118,19 @@ static int heartbeat_reboot_notifier(struct notifier_block *nb,
111118
return NOTIFY_DONE;
112119
}
113120

121+
static int heartbeat_panic_notifier(struct notifier_block *nb,
122+
unsigned long code, void *unused)
123+
{
124+
panic_heartbeats = 1;
125+
return NOTIFY_DONE;
126+
}
127+
114128
static struct notifier_block heartbeat_reboot_nb = {
115129
.notifier_call = heartbeat_reboot_notifier,
116130
};
117131

118132
static struct notifier_block heartbeat_panic_nb = {
119-
.notifier_call = heartbeat_reboot_notifier,
133+
.notifier_call = heartbeat_panic_notifier,
120134
};
121135

122136
static int __init heartbeat_trig_init(void)

0 commit comments

Comments
 (0)