Skip to content

Commit 92c50ed

Browse files
rostedtjnettlet
authored andcommitted
acpi/rt: Convert acpi_gbl_hardware lock back to a raw_spinlock_t
We hit the following bug with 3.6-rt: [ 5.898990] BUG: scheduling while atomic: swapper/3/0/0x00000002 [ 5.898991] no locks held by swapper/3/0. [ 5.898993] Modules linked in: [ 5.898996] Pid: 0, comm: swapper/3 Not tainted 3.6.11-rt28.19.el6rt.x86_64.debug #1 [ 5.898997] Call Trace: [ 5.899011] [<ffffffff810804e7>] __schedule_bug+0x67/0x90 [ 5.899028] [<ffffffff81577923>] __schedule+0x793/0x7a0 [ 5.899032] [<ffffffff810b4e40>] ? debug_rt_mutex_print_deadlock+0x50/0x200 [ 5.899034] [<ffffffff81577b89>] schedule+0x29/0x70 [ 5.899036] BUG: scheduling while atomic: swapper/7/0/0x00000002 [ 5.899037] no locks held by swapper/7/0. [ 5.899039] [<ffffffff81578525>] rt_spin_lock_slowlock+0xe5/0x2f0 [ 5.899040] Modules linked in: [ 5.899041] [ 5.899045] [<ffffffff81579a58>] ? _raw_spin_unlock_irqrestore+0x38/0x90 [ 5.899046] Pid: 0, comm: swapper/7 Not tainted 3.6.11-rt28.19.el6rt.x86_64.debug #1 [ 5.899047] Call Trace: [ 5.899049] [<ffffffff81578bc6>] rt_spin_lock+0x16/0x40 [ 5.899052] [<ffffffff810804e7>] __schedule_bug+0x67/0x90 [ 5.899054] [<ffffffff8157d3f0>] ? notifier_call_chain+0x80/0x80 [ 5.899056] [<ffffffff81577923>] __schedule+0x793/0x7a0 [ 5.899059] [<ffffffff812f2034>] acpi_os_acquire_lock+0x1f/0x23 [ 5.899062] [<ffffffff810b4e40>] ? debug_rt_mutex_print_deadlock+0x50/0x200 [ 5.899068] [<ffffffff8130be64>] acpi_write_bit_register+0x33/0xb0 [ 5.899071] [<ffffffff81577b89>] schedule+0x29/0x70 [ 5.899072] [<ffffffff8130be13>] ? acpi_read_bit_register+0x33/0x51 [ 5.899074] [<ffffffff81578525>] rt_spin_lock_slowlock+0xe5/0x2f0 [ 5.899077] [<ffffffff8131d1fc>] acpi_idle_enter_bm+0x8a/0x28e [ 5.899079] [<ffffffff81579a58>] ? _raw_spin_unlock_irqrestore+0x38/0x90 [ 5.899081] [<ffffffff8107e5da>] ? this_cpu_load+0x1a/0x30 [ 5.899083] [<ffffffff81578bc6>] rt_spin_lock+0x16/0x40 [ 5.899087] [<ffffffff8144c759>] cpuidle_enter+0x19/0x20 [ 5.899088] [<ffffffff8157d3f0>] ? notifier_call_chain+0x80/0x80 [ 5.899090] [<ffffffff8144c777>] cpuidle_enter_state+0x17/0x50 [ 5.899092] [<ffffffff812f2034>] acpi_os_acquire_lock+0x1f/0x23 [ 5.899094] [<ffffffff8144d1a1>] cpuidle899101] [<ffffffff8130be13>] ? As the acpi code disables interrupts in acpi_idle_enter_bm, and calls code that grabs the acpi lock, it causes issues as the lock is currently in RT a sleeping lock. The lock was converted from a raw to a sleeping lock due to some previous issues, and tests that showed it didn't seem to matter. Unfortunately, it did matter for one of our boxes. This patch converts the lock back to a raw lock. I've run this code on a few of my own machines, one being my laptop that uses the acpi quite extensively. I've been able to suspend and resume without issues. [ tglx: Made the change exclusive for acpi_gbl_hardware_lock ] Signed-off-by: Steven Rostedt <rostedt@goodmis.org> Cc: John Kacur <jkacur@gmail.com> Cc: Clark Williams <clark@redhat.com> Link: http://lkml.kernel.org/r/1360765565.23152.5.camel@gandalf.local.home Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
1 parent 395bbc4 commit 92c50ed

File tree

5 files changed

+22
-7
lines changed

5 files changed

+22
-7
lines changed

drivers/acpi/acpica/acglobal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ ACPI_GLOBAL(u8, acpi_gbl_global_lock_pending);
116116
* interrupt level
117117
*/
118118
ACPI_GLOBAL(acpi_spinlock, acpi_gbl_gpe_lock); /* For GPE data structs and registers */
119-
ACPI_GLOBAL(acpi_spinlock, acpi_gbl_hardware_lock); /* For ACPI H/W except GPE registers */
119+
ACPI_GLOBAL(acpi_raw_spinlock, acpi_gbl_hardware_lock); /* For ACPI H/W except GPE registers */
120120
ACPI_GLOBAL(acpi_spinlock, acpi_gbl_reference_count_lock);
121121

122122
/* Mutex for _OSI support */

drivers/acpi/acpica/hwregs.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -363,14 +363,14 @@ acpi_status acpi_hw_clear_acpi_status(void)
363363
ACPI_BITMASK_ALL_FIXED_STATUS,
364364
ACPI_FORMAT_UINT64(acpi_gbl_xpm1a_status.address)));
365365

366-
lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock);
366+
raw_spin_lock_irqsave(acpi_gbl_hardware_lock, lock_flags);
367367

368368
/* Clear the fixed events in PM1 A/B */
369369

370370
status = acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS,
371371
ACPI_BITMASK_ALL_FIXED_STATUS);
372372

373-
acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags);
373+
raw_spin_unlock_irqrestore(acpi_gbl_hardware_lock, lock_flags);
374374

375375
if (ACPI_FAILURE(status)) {
376376
goto exit;

drivers/acpi/acpica/hwxface.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,7 @@ acpi_status acpi_write_bit_register(u32 register_id, u32 value)
373373
return_ACPI_STATUS(AE_BAD_PARAMETER);
374374
}
375375

376-
lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock);
376+
raw_spin_lock_irqsave(acpi_gbl_hardware_lock, lock_flags);
377377

378378
/*
379379
* At this point, we know that the parent register is one of the
@@ -434,7 +434,7 @@ acpi_status acpi_write_bit_register(u32 register_id, u32 value)
434434

435435
unlock_and_exit:
436436

437-
acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags);
437+
raw_spin_unlock_irqrestore(acpi_gbl_hardware_lock, lock_flags);
438438
return_ACPI_STATUS(status);
439439
}
440440

drivers/acpi/acpica/utmutex.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ acpi_status acpi_ut_mutex_initialize(void)
8888
return_ACPI_STATUS (status);
8989
}
9090

91-
status = acpi_os_create_lock (&acpi_gbl_hardware_lock);
91+
status = acpi_os_create_raw_lock (&acpi_gbl_hardware_lock);
9292
if (ACPI_FAILURE (status)) {
9393
return_ACPI_STATUS (status);
9494
}
@@ -145,7 +145,7 @@ void acpi_ut_mutex_terminate(void)
145145
/* Delete the spinlocks */
146146

147147
acpi_os_delete_lock(acpi_gbl_gpe_lock);
148-
acpi_os_delete_lock(acpi_gbl_hardware_lock);
148+
acpi_os_delete_raw_lock(acpi_gbl_hardware_lock);
149149
acpi_os_delete_lock(acpi_gbl_reference_count_lock);
150150

151151
/* Delete the reader/writer lock */

include/acpi/platform/aclinux.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@
133133

134134
#define acpi_cache_t struct kmem_cache
135135
#define acpi_spinlock spinlock_t *
136+
#define acpi_raw_spinlock raw_spinlock_t *
136137
#define acpi_cpu_flags unsigned long
137138

138139
/* Use native linux version of acpi_os_allocate_zeroed */
@@ -151,6 +152,20 @@
151152
#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_get_thread_id
152153
#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_create_lock
153154

155+
#define acpi_os_create_raw_lock(__handle) \
156+
({ \
157+
raw_spinlock_t *lock = ACPI_ALLOCATE(sizeof(*lock)); \
158+
\
159+
if (lock) { \
160+
*(__handle) = lock; \
161+
raw_spin_lock_init(*(__handle)); \
162+
} \
163+
lock ? AE_OK : AE_NO_MEMORY; \
164+
})
165+
166+
#define acpi_os_delete_raw_lock(__handle) kfree(__handle)
167+
168+
154169
/*
155170
* OSL interfaces used by debugger/disassembler
156171
*/

0 commit comments

Comments
 (0)