Skip to content

Commit

Permalink
ledtrig-cpu: kill useless mutex to fix sleep in atomic context
Browse files Browse the repository at this point in the history
Seeing the following every time the CPU enters or leaves idle on a
Beagleboard:

BUG: sleeping function called from invalid context at kernel/mutex.c:269
in_atomic(): 1, irqs_disabled(): 0, pid: 0, name: swapper/0
no locks held by swapper/0/0.
[<c001659c>] (unwind_backtrace+0x0/0xf8) from [<c05aaa7c>] (mutex_lock_nested+0x24/0x380)
[<c05aaa7c>] (mutex_lock_nested+0x24/0x380) from [<c043bd1c>] (ledtrig_cpu+0x38/0x88)
[<c043bd1c>] (ledtrig_cpu+0x38/0x88) from [<c000f4b0>] (cpu_idle+0xf4/0x120)
[<c000f4b0>] (cpu_idle+0xf4/0x120) from [<c07e47c8>] (start_kernel+0x2bc/0x30c)

Miles Lane has reported seeing similar splats during system suspend.

The mutex in struct led_trigger_cpu appears to have no function: it
resides in a per-cpu data structure which never changes after the
trigger is registered.  So just remove it.

Reported-by: Miles Lane <miles.lane@gmail.com>
Signed-off-by: Nathan Lynch <ntl@pobox.com>
Signed-off-by: Bryan Wu <roc@roc-samos.(none)>
  • Loading branch information
Nathan Lynch authored and Bryan Wu committed Nov 11, 2012
1 parent 77b6706 commit 0b8728d
Showing 1 changed file with 0 additions and 21 deletions.
21 changes: 0 additions & 21 deletions drivers/leds/ledtrig-cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@
struct led_trigger_cpu {
char name[MAX_NAME_LEN];
struct led_trigger *_trig;
struct mutex lock;
int lock_is_inited;
};

static DEFINE_PER_CPU(struct led_trigger_cpu, cpu_trig);
Expand All @@ -50,12 +48,6 @@ void ledtrig_cpu(enum cpu_led_event ledevt)
{
struct led_trigger_cpu *trig = &__get_cpu_var(cpu_trig);

/* mutex lock should be initialized before calling mutex_call() */
if (!trig->lock_is_inited)
return;

mutex_lock(&trig->lock);

/* Locate the correct CPU LED */
switch (ledevt) {
case CPU_LED_IDLE_END:
Expand All @@ -75,8 +67,6 @@ void ledtrig_cpu(enum cpu_led_event ledevt)
/* Will leave the LED as it is */
break;
}

mutex_unlock(&trig->lock);
}
EXPORT_SYMBOL(ledtrig_cpu);

Expand Down Expand Up @@ -117,14 +107,9 @@ static int __init ledtrig_cpu_init(void)
for_each_possible_cpu(cpu) {
struct led_trigger_cpu *trig = &per_cpu(cpu_trig, cpu);

mutex_init(&trig->lock);

snprintf(trig->name, MAX_NAME_LEN, "cpu%d", cpu);

mutex_lock(&trig->lock);
led_trigger_register_simple(trig->name, &trig->_trig);
trig->lock_is_inited = 1;
mutex_unlock(&trig->lock);
}

register_syscore_ops(&ledtrig_cpu_syscore_ops);
Expand All @@ -142,15 +127,9 @@ static void __exit ledtrig_cpu_exit(void)
for_each_possible_cpu(cpu) {
struct led_trigger_cpu *trig = &per_cpu(cpu_trig, cpu);

mutex_lock(&trig->lock);

led_trigger_unregister_simple(trig->_trig);
trig->_trig = NULL;
memset(trig->name, 0, MAX_NAME_LEN);
trig->lock_is_inited = 0;

mutex_unlock(&trig->lock);
mutex_destroy(&trig->lock);
}

unregister_syscore_ops(&ledtrig_cpu_syscore_ops);
Expand Down

0 comments on commit 0b8728d

Please sign in to comment.