public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: "Rafael J. Wysocki" <rjw@sisk.pl>
To: ACPI Devel Maling List <linux-acpi@vger.kernel.org>
Cc: Alexey Starikovskiy <astarikovskiy@suse.de>,
	Len Brown <lenb@kernel.org>,
	pm list <linux-pm@lists.linux-foundation.org>,
	Thomas Renninger <trenn@suse.de>,
	Maxim Levitsky <maximlevitsky@gmail.com>,
	Matthew Garrett <mjg59@srcf.ucam.org>,
	LKML <linux-kernel@vger.kernel.org>
Subject: [RFC][RFT][PATCH] ACPI: Protection from suspending in the middle of EC transaction
Date: Sun, 31 Jan 2010 00:29:48 +0100	[thread overview]
Message-ID: <201001310029.48717.rjw@sisk.pl> (raw)

Hi,

While Maxim is testing if the patch below helps with
http://bugzilla.kernel.org/show_bug.cgi?id=14668
I think it's necessary anyway.

The problem is that currently there's nothing to prevent us from suspending in
the middle of an EC transaction in progress, at least as far as I can see.
As a result, we can suspend with the ACPI global lock held or something like
this, which leads to problems especially for hibernation (if the resume kernel
passes control to the image kernel in the middle of an EC transaction, things
aren't nice).  For this reason I think we should wait until there are no EC
transactions in progress before we suspend and we should prevent any new
EC transactions from starting after that point.  The patch below does that.

However, it does that in the EC's suspend callback, which may be too early,
because there still is _PTS to run, so it might be necessary to do that later.
On the other hand, the mechanics behind the ACPI global lock, which is
acquired in acpi_ec_transaction(), requires that interrupts work, because
otherwise there may be a problem if the global lock is not actually acquired
after ACPI_ACQUIRE_GLOBAL_LOCK(), so the last place in which to
wait for EC transactions to complete seems to be the platform suspend
.prepare() callback.  Unfortunately, it's not implemented at the moment for
ACPI and it doesn't have a hibernate counterpart and that's why I'd rather use
the patch below, unless it's known to break things for someone.  So, if you
can, please test it and tell me if you have any problems with it.

Of course, comments are welcome as well.

Thanks,
Rafael

---
 drivers/acpi/ec.c |   17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

Index: linux-2.6/drivers/acpi/ec.c
===================================================================
--- linux-2.6.orig/drivers/acpi/ec.c
+++ linux-2.6/drivers/acpi/ec.c
@@ -76,8 +76,9 @@ enum ec_command {
 enum {
 	EC_FLAGS_QUERY_PENDING,		/* Query is pending */
 	EC_FLAGS_GPE_STORM,		/* GPE storm detected */
-	EC_FLAGS_HANDLERS_INSTALLED	/* Handlers for GPE and
+	EC_FLAGS_HANDLERS_INSTALLED,	/* Handlers for GPE and
 					 * OpReg are installed */
+	EC_FLAGS_SUSPENDED,		/* Driver is suspended */
 };
 
 /* If we find an EC via the ECDT, we need to keep a ptr to its context */
@@ -291,6 +292,10 @@ static int acpi_ec_transaction(struct ac
 	if (t->rdata)
 		memset(t->rdata, 0, t->rlen);
 	mutex_lock(&ec->lock);
+	if (test_bit(EC_FLAGS_SUSPENDED, &ec->flags)) {
+		status = -EBUSY;
+		goto unlock;
+	}
 	if (ec->global_lock) {
 		status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
 		if (ACPI_FAILURE(status)) {
@@ -1059,16 +1064,26 @@ error:
 static int acpi_ec_suspend(struct acpi_device *device, pm_message_t state)
 {
 	struct acpi_ec *ec = acpi_driver_data(device);
+
+	mutex_lock(&ec->lock);
+	/* Prevent transactions from happening while suspended */
+	set_bit(EC_FLAGS_SUSPENDED, &ec->flags);
 	/* Stop using GPE */
 	acpi_disable_gpe(NULL, ec->gpe);
+	mutex_unlock(&ec->lock);
 	return 0;
 }
 
 static int acpi_ec_resume(struct acpi_device *device)
 {
 	struct acpi_ec *ec = acpi_driver_data(device);
+
+	mutex_lock(&ec->lock);
 	/* Enable use of GPE back */
 	acpi_enable_gpe(NULL, ec->gpe);
+	/* Allow transactions to happen again */
+	set_bit(EC_FLAGS_SUSPENDED, &ec->flags);
+	mutex_unlock(&ec->lock);
 	return 0;
 }
 

             reply	other threads:[~2010-01-30 23:29 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-01-30 23:29 Rafael J. Wysocki [this message]
2010-01-31 14:11 ` [RFC][RFT][PATCH] ACPI: Protection from suspending in the middle of EC transaction Alan Jenkins
2010-01-31 17:09   ` Maxim Levitsky
2010-02-01  9:46     ` Henrique de Moraes Holschuh
2010-02-01 10:22       ` Alexey Starikovskiy
2010-02-01 22:42         ` Rafael J. Wysocki
2010-02-02 20:23           ` [PATCH] ACPI / EC: Remover race between EC driver and suspend process (was: Re: [RFC][RFT][PATCH] ACPI: Protection from suspending in the middle of EC transaction) Rafael J. Wysocki
2010-01-31 20:41 ` [RFC][RFT][PATCH] ACPI: Protection from suspending in the middle of EC transaction Maxim Levitsky
2010-01-31 21:09   ` Rafael J. Wysocki
2010-01-31 22:31     ` Rafael J. Wysocki
2010-02-03  0:32 ` [PATCH] ACPI / EC: Remove race between EC driver and suspend process (rev. 2) (was: Re: [RFC][RFT][PATCH] ACPI: Protection from suspending in the middle of EC transaction) Rafael J. Wysocki
2010-02-04  0:33   ` [PATCH] ACPI / EC: Remove race between EC driver and suspend process (rev. 3) Rafael J. Wysocki

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=201001310029.48717.rjw@sisk.pl \
    --to=rjw@sisk.pl \
    --cc=astarikovskiy@suse.de \
    --cc=lenb@kernel.org \
    --cc=linux-acpi@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pm@lists.linux-foundation.org \
    --cc=maximlevitsky@gmail.com \
    --cc=mjg59@srcf.ucam.org \
    --cc=trenn@suse.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox