acpi-ec-pm-fix-race-between-ec-transactions-and-system-suspend.patch
another possible fix for suspend/resume problems.
This commit is contained in:
parent
45fbfae2b4
commit
e00d73683c
|
@ -0,0 +1,215 @@
|
|||
From: Rafael J. Wysocki <rjw@sisk.pl>
|
||||
Date: Thu, 8 Apr 2010 23:39:40 +0000 (+0200)
|
||||
Subject: ACPI / EC / PM: Fix race between EC transactions and system suspend
|
||||
X-Git-Tag: v2.6.35-rc2~39^2~3
|
||||
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=d5a64513c6a171262082c250592c062e97a2c693
|
||||
|
||||
ACPI / EC / PM: Fix race between EC transactions and system suspend
|
||||
|
||||
There still is a race that may result in suspending the system in
|
||||
the middle of an EC transaction in progress, which leads to problems
|
||||
(like the kernel thinking that the ACPI global lock is held during
|
||||
resume while in fact it's not).
|
||||
|
||||
To remove the race condition, modify the ACPI platform suspend and
|
||||
hibernate callbacks so that EC transactions are blocked right after
|
||||
executing the _PTS global control method and are allowed to happen
|
||||
again right after the low-level wakeup.
|
||||
|
||||
Introduce acpi_pm_freeze() that will disable GPEs, wait until the
|
||||
event queues are empty and block EC transactions. Use it wherever
|
||||
GPEs are disabled in preparation for switching local interrupts off.
|
||||
Introduce acpi_pm_thaw() that will allow EC transactions to happen
|
||||
again and enable runtime GPEs. Use it to balance acpi_pm_freeze()
|
||||
wherever necessary.
|
||||
|
||||
In addition to that use acpi_ec_resume_transactions_early() to
|
||||
unblock EC transactions as early as reasonably possible during
|
||||
resume. Also unblock EC transactions in acpi_hibernation_finish()
|
||||
and in the analogous suspend routine to make sure that the EC
|
||||
transactions are enabled in all error paths.
|
||||
|
||||
Fixes https://bugzilla.kernel.org/show_bug.cgi?id=14668
|
||||
|
||||
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
|
||||
Reported-and-tested-by: Maxim Levitsky <maximlevitsky@gmail.com>
|
||||
Signed-off-by: Len Brown <len.brown@intel.com>
|
||||
---
|
||||
|
||||
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
|
||||
index f2234db..2c2b73a 100644
|
||||
--- a/drivers/acpi/ec.c
|
||||
+++ b/drivers/acpi/ec.c
|
||||
@@ -485,6 +485,16 @@ void acpi_ec_resume_transactions(void)
|
||||
mutex_unlock(&ec->lock);
|
||||
}
|
||||
|
||||
+void acpi_ec_resume_transactions_early(void)
|
||||
+{
|
||||
+ /*
|
||||
+ * Allow transactions to happen again (this function is called from
|
||||
+ * atomic context during wakeup, so we don't need to acquire the mutex).
|
||||
+ */
|
||||
+ if (first_ec)
|
||||
+ clear_bit(EC_FLAGS_FROZEN, &first_ec->flags);
|
||||
+}
|
||||
+
|
||||
static int acpi_ec_query_unlocked(struct acpi_ec *ec, u8 * data)
|
||||
{
|
||||
int result;
|
||||
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
|
||||
index e284113..0ec48c7 100644
|
||||
--- a/drivers/acpi/internal.h
|
||||
+++ b/drivers/acpi/internal.h
|
||||
@@ -51,6 +51,7 @@ int acpi_ec_ecdt_probe(void);
|
||||
int acpi_boot_ec_enable(void);
|
||||
void acpi_ec_suspend_transactions(void);
|
||||
void acpi_ec_resume_transactions(void);
|
||||
+void acpi_ec_resume_transactions_early(void);
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
Suspend/Resume
|
||||
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
|
||||
index baa76bb..24741ac 100644
|
||||
--- a/drivers/acpi/sleep.c
|
||||
+++ b/drivers/acpi/sleep.c
|
||||
@@ -110,11 +110,13 @@ void __init acpi_old_suspend_ordering(void)
|
||||
}
|
||||
|
||||
/**
|
||||
- * acpi_pm_disable_gpes - Disable the GPEs.
|
||||
+ * acpi_pm_freeze - Disable the GPEs and suspend EC transactions.
|
||||
*/
|
||||
-static int acpi_pm_disable_gpes(void)
|
||||
+static int acpi_pm_freeze(void)
|
||||
{
|
||||
acpi_disable_all_gpes();
|
||||
+ acpi_os_wait_events_complete(NULL);
|
||||
+ acpi_ec_suspend_transactions();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -142,7 +144,8 @@ static int acpi_pm_prepare(void)
|
||||
int error = __acpi_pm_prepare();
|
||||
|
||||
if (!error)
|
||||
- acpi_disable_all_gpes();
|
||||
+ acpi_pm_freeze();
|
||||
+
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -275,6 +278,8 @@ static int acpi_suspend_enter(suspend_state_t pm_state)
|
||||
* acpi_leave_sleep_state will reenable specific GPEs later
|
||||
*/
|
||||
acpi_disable_all_gpes();
|
||||
+ /* Allow EC transactions to happen. */
|
||||
+ acpi_ec_resume_transactions_early();
|
||||
|
||||
local_irq_restore(flags);
|
||||
printk(KERN_DEBUG "Back to C!\n");
|
||||
@@ -286,6 +291,12 @@ static int acpi_suspend_enter(suspend_state_t pm_state)
|
||||
return ACPI_SUCCESS(status) ? 0 : -EFAULT;
|
||||
}
|
||||
|
||||
+static void acpi_suspend_finish(void)
|
||||
+{
|
||||
+ acpi_ec_resume_transactions();
|
||||
+ acpi_pm_finish();
|
||||
+}
|
||||
+
|
||||
static int acpi_suspend_state_valid(suspend_state_t pm_state)
|
||||
{
|
||||
u32 acpi_state;
|
||||
@@ -307,7 +318,7 @@ static struct platform_suspend_ops acpi_suspend_ops = {
|
||||
.begin = acpi_suspend_begin,
|
||||
.prepare_late = acpi_pm_prepare,
|
||||
.enter = acpi_suspend_enter,
|
||||
- .wake = acpi_pm_finish,
|
||||
+ .wake = acpi_suspend_finish,
|
||||
.end = acpi_pm_end,
|
||||
};
|
||||
|
||||
@@ -333,9 +344,9 @@ static int acpi_suspend_begin_old(suspend_state_t pm_state)
|
||||
static struct platform_suspend_ops acpi_suspend_ops_old = {
|
||||
.valid = acpi_suspend_state_valid,
|
||||
.begin = acpi_suspend_begin_old,
|
||||
- .prepare_late = acpi_pm_disable_gpes,
|
||||
+ .prepare_late = acpi_pm_freeze,
|
||||
.enter = acpi_suspend_enter,
|
||||
- .wake = acpi_pm_finish,
|
||||
+ .wake = acpi_suspend_finish,
|
||||
.end = acpi_pm_end,
|
||||
.recover = acpi_pm_finish,
|
||||
};
|
||||
@@ -586,6 +597,7 @@ static int acpi_hibernation_enter(void)
|
||||
static void acpi_hibernation_finish(void)
|
||||
{
|
||||
hibernate_nvs_free();
|
||||
+ acpi_ec_resume_transactions();
|
||||
acpi_pm_finish();
|
||||
}
|
||||
|
||||
@@ -606,17 +618,11 @@ static void acpi_hibernation_leave(void)
|
||||
}
|
||||
/* Restore the NVS memory area */
|
||||
hibernate_nvs_restore();
|
||||
+ /* Allow EC transactions to happen. */
|
||||
+ acpi_ec_resume_transactions_early();
|
||||
}
|
||||
|
||||
-static int acpi_pm_pre_restore(void)
|
||||
-{
|
||||
- acpi_disable_all_gpes();
|
||||
- acpi_os_wait_events_complete(NULL);
|
||||
- acpi_ec_suspend_transactions();
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static void acpi_pm_restore_cleanup(void)
|
||||
+static void acpi_pm_thaw(void)
|
||||
{
|
||||
acpi_ec_resume_transactions();
|
||||
acpi_enable_all_runtime_gpes();
|
||||
@@ -630,8 +636,8 @@ static struct platform_hibernation_ops acpi_hibernation_ops = {
|
||||
.prepare = acpi_pm_prepare,
|
||||
.enter = acpi_hibernation_enter,
|
||||
.leave = acpi_hibernation_leave,
|
||||
- .pre_restore = acpi_pm_pre_restore,
|
||||
- .restore_cleanup = acpi_pm_restore_cleanup,
|
||||
+ .pre_restore = acpi_pm_freeze,
|
||||
+ .restore_cleanup = acpi_pm_thaw,
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -663,12 +669,9 @@ static int acpi_hibernation_begin_old(void)
|
||||
|
||||
static int acpi_hibernation_pre_snapshot_old(void)
|
||||
{
|
||||
- int error = acpi_pm_disable_gpes();
|
||||
-
|
||||
- if (!error)
|
||||
- hibernate_nvs_save();
|
||||
-
|
||||
- return error;
|
||||
+ acpi_pm_freeze();
|
||||
+ hibernate_nvs_save();
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -680,11 +683,11 @@ static struct platform_hibernation_ops acpi_hibernation_ops_old = {
|
||||
.end = acpi_pm_end,
|
||||
.pre_snapshot = acpi_hibernation_pre_snapshot_old,
|
||||
.finish = acpi_hibernation_finish,
|
||||
- .prepare = acpi_pm_disable_gpes,
|
||||
+ .prepare = acpi_pm_freeze,
|
||||
.enter = acpi_hibernation_enter,
|
||||
.leave = acpi_hibernation_leave,
|
||||
- .pre_restore = acpi_pm_pre_restore,
|
||||
- .restore_cleanup = acpi_pm_restore_cleanup,
|
||||
+ .pre_restore = acpi_pm_freeze,
|
||||
+ .restore_cleanup = acpi_pm_thaw,
|
||||
.recover = acpi_pm_finish,
|
||||
};
|
||||
#endif /* CONFIG_HIBERNATION */
|
16
kernel.spec
16
kernel.spec
|
@ -48,7 +48,7 @@ Summary: The Linux kernel
|
|||
# reset this by hand to 1 (or to 0 and then use rpmdev-bumpspec).
|
||||
# scripts/rebase.sh should be made to do that for you, actually.
|
||||
#
|
||||
%global baserelease 51
|
||||
%global baserelease 52
|
||||
%global fedora_build %{baserelease}
|
||||
|
||||
# base_sublevel is the kernel version we're starting with and patching
|
||||
|
@ -771,10 +771,13 @@ Patch12480: kprobes-x86-fix-kprobes-to-skip-prefixes-correctly.patch
|
|||
Patch12490: dell-wmi-add-support-for-eject-key.patch
|
||||
Patch12500: irda-correctly-clean-up-self-ias_obj-on-irda_bind-failure.patch
|
||||
Patch12510: wireless-extensions-fix-kernel-heap-content-leak.patch
|
||||
|
||||
Patch12515: sanity-check-bond-proc_entry.patch
|
||||
Patch12516: asix-use-eth_mac_addr.patch
|
||||
Patch12517: flexcop-fix-xlate_proc_name-warning.patch
|
||||
|
||||
Patch12520: acpi-ec-pm-fix-race-between-ec-transactions-and-system-suspend.patch
|
||||
|
||||
%endif
|
||||
|
||||
BuildRoot: %{_tmppath}/kernel-%{KVERREL}-root
|
||||
|
@ -1454,6 +1457,9 @@ ApplyPatch asix-use-eth_mac_addr.patch
|
|||
# bz #575873
|
||||
ApplyPatch flexcop-fix-xlate_proc_name-warning.patch
|
||||
|
||||
# another fix for suspend/resume bugs
|
||||
ApplyPatch acpi-ec-pm-fix-race-between-ec-transactions-and-system-suspend.patch
|
||||
|
||||
# END OF PATCH APPLICATIONS
|
||||
|
||||
%endif
|
||||
|
@ -2075,9 +2081,13 @@ fi
|
|||
|
||||
|
||||
%changelog
|
||||
* Fri Sep 03 2010 Kyle McMartin <kmcmartin@redhat.com> 2.6.34.6-52
|
||||
* Fri Sep 03 2010 Chuck Ebbert <cebbert@redhat.com> 2.6.34.6-52
|
||||
- acpi-ec-pm-fix-race-between-ec-transactions-and-system-suspend.patch:
|
||||
another possible fix for suspend/resume problems.
|
||||
|
||||
* Fri Sep 03 2010 Kyle McMartin <kmcmartin@redhat.com>
|
||||
- sanity-check-bond-proc_entry.patch (rhbz#604630)
|
||||
- asix.c: stub out set_mac_address in case it's breaking things (rhbz#629871)
|
||||
- asix.c: stub out set_mac_address in case it's breaking things (rhbz#625479)
|
||||
- default to pci=nocrs
|
||||
- flexcop: fix registering braindead stupid names (#575873)
|
||||
|
||||
|
|
Loading…
Reference in New Issue