acpi: Fix possible recursive locking in hwregs.c
Subsystems (2)
PATCH 1/1 acpi: Fix possible recursive locking in hwregs.c
Calling pm-suspend might trigger a recursive lock in it's code path. In function acpi_hw_clear_acpi_status, acpi_os_release_lock holds the lock acpi_gbl_hardware_lock before calling acpi_hw_register_write(), then without releasing acpi_gbl_hardware_lock, this function calls acpi_ev_walk_gpe_list, which also tries to hold acpi_gbl_hardware_lock and thus causes possible recursive lock.
Following patch fixes this scenario by just releasing acpi_gbl_hardware_lock before calling acpi_ev_walk_gpe_list.
[This patch was created against 3.0-rc3. Since kernel.org is down, I don't have the updated tree. So, before applying it might require some adjustment.]
---
drivers/acpi/acpica/hwregs.c +3 -1
@@ -269,6 +269,9 @@ acpi_status acpi_hw_clear_acpi_status(void) status =acpi_hw_register_write (ACPI_REGISTER_PM1_STATUS ,ACPI_BITMASK_ALL_FIXED_STATUS ); + +acpi_os_release_lock (acpi_gbl_hardware_lock, lock_flags); +if (ACPI_FAILURE (status)) { goto unlock_and_exit; }
@@ -278,7 +281,6 @@ acpi_status acpi_hw_clear_acpi_status(void) status =acpi_ev_walk_gpe_list (acpi_hw_clear_gpe_block,NULL ); unlock_and_exit: -acpi_os_release_lock (acpi_gbl_hardware_lock, lock_flags);return_ACPI_STATUS (status); }
Quoted 4 lines · Rakib Mullick
Calling pm-suspend might trigger a recursive lock in it's code path. In function
acpi_hw_clear_acpi_status,acpi_os_release_lockholds the lockacpi_gbl_hardware_lockbefore callingacpi_hw_register_write(), then without releasingacpi_gbl_hardware_lock, this function callsacpi_ev_walk_gpe_list, which also tries to holdacpi_gbl_hardware_lockand thus causes possible recursive lock.
No, acpi_ev_walk_gpe_list holds acpi_gbl_gpe_lock.
Lin Ming
Quoted 33 lines
Following patch fixes this scenario by just releasing
acpi_gbl_hardware_lockbefore callingacpi_ev_walk_gpe_list.[This patch was created against 3.0-rc3. Since kernel.org is down, I don't have the updated tree. So, before applying it might require some adjustment.]
Signed-off-by Rakib Mullick <[email protected]>---
drivers/acpi/acpica/hwregs.c +3
-0@@ -269,6 +269,9 @@ acpi_status acpi_hw_clear_acpi_status(void) status = acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS, ACPI_BITMASK_ALL_FIXED_STATUS); + + acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags); + if (ACPI_FAILURE(status)) { goto unlock_and_exit; }@@ -278,7 +281,6 @@ acpi_status acpi_hw_clear_acpi_status(void) status = acpi_ev_walk_gpe_list(acpi_hw_clear_gpe_block, NULL);
unlock_and_exit:
-acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags);return_ACPI_STATUS(status);
}
Quoted 6 lines
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Quoted 8 lines · Lin Ming
Quoted 4 lines · Rakib Mullick
Calling pm-suspend might trigger a recursive lock in it's code path. In function
acpi_hw_clear_acpi_status,acpi_os_release_lockholds the lockacpi_gbl_hardware_lockbefore callingacpi_hw_register_write(), then without releasingacpi_gbl_hardware_lock, this function callsacpi_ev_walk_gpe_list, which also tries to holdacpi_gbl_hardware_lockand thus causes possible recursive lock.No,
acpi_ev_walk_gpe_listholdsacpi_gbl_gpe_lock.
Yes, right. Actually, acpi_os_release_lock() tries to hold acpi_gbl_gpe_lock without releasing acpi_gbl_hardware_lock. Right?
Thanks,
Rakib
Quoted 11 lines · Rakib Mullick
Quoted 8 lines · Lin Ming
Quoted 4 lines · Rakib Mullick
Calling pm-suspend might trigger a recursive lock in it's code path. In function
acpi_hw_clear_acpi_status,acpi_os_release_lockholds the lockacpi_gbl_hardware_lockbefore callingacpi_hw_register_write(), then without releasingacpi_gbl_hardware_lock, this function callsacpi_ev_walk_gpe_list, which also tries to holdacpi_gbl_hardware_lockand thus causes possible recursive lock.No,
acpi_ev_walk_gpe_listholdsacpi_gbl_gpe_lock.Yes, right. Actually,
acpi_os_release_lock()tries to holdacpi_gbl_gpe_lockwithout releasingacpi_gbl_hardware_lock. Right?
Do you mean "acpi_ev_walk_gpe_list() tries to hold acpi_gbl_gpe_lock..."?
We have below locks sequence. I don't see the problem.
acpi_hw_clear_acpi_status:
<acquire acpi_gbl_hardware_lock>
acpi_ev_walk_gpe_list:
<acquire acpi_gbl_gpe_lock>
...
<release acpi_gbl_gpe_lock>
...
<release acpi_gbl_hardware_lock>Quoted 3 lines
Thanks,
Rakib
Quoted 8 lines · Lin Ming
Quoted 7 lines · Rakib Mullick
Quoted 6 lines · Lin Ming
Quoted 4 lines · Rakib Mullick
Calling pm-suspend might trigger a recursive lock in it's code path. In function
acpi_hw_clear_acpi_status,acpi_os_release_lockholds the lockacpi_gbl_hardware_lockbefore callingacpi_hw_register_write(), then without releasingacpi_gbl_hardware_lock, this function callsacpi_ev_walk_gpe_list, which also tries to holdacpi_gbl_hardware_lockand thus causes possible recursive lock.
Quoted 8 lines
Quoted 4 lines
Quoted 2 lines
No,
acpi_ev_walk_gpe_listholdsacpi_gbl_gpe_lock.Yes, right. Actually,
acpi_os_release_lock()tries to holdacpi_gbl_gpe_lockwithout releasingacpi_gbl_hardware_lock. Right?Do you mean "
acpi_ev_walk_gpe_list()tries to holdacpi_gbl_gpe_lock..."?
I wanted to mean, acpi_os_acquire_lock() tries to hold acpi_gbl_gpe_lock without releasing acpi_gbl_hardware_lock. Actually, this recursive locking scenario showed up on my modified kernel and fails to suspend. But, never happened on mainline kernel. Looking at the warning it seems to me that, it's safe to release the acpi_gbl_hardware_lock before calling acpi_ev_walk_gpe_list() and also solves the problem. Calling acpi_ev_walk_gpe_list() doesn't require acpi_gbl_hardware_lock to be held. This is the reason behind the patch.
Quoted 4 lines
We have below locks sequence. I don't see the problem.
acpi_hw_clear_acpi_status:
Quoted 15 lines
<acquire
acpi_gbl_hardware_lock>
acpi_ev_walk_gpe_list:
<acquireacpi_gbl_gpe_lock>
...
<releaseacpi_gbl_gpe_lock>
...
<releaseacpi_gbl_hardware_lock>Quoted 3 lines
Thanks,
Rakib
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html