All of lore.kernel.org
 help / color / mirror / Atom feed
From: Chris Chiu <chiu@endlessm.com>
To: "Rafael J. Wysocki" <rjw@rjwysocki.net>
Cc: Linux ACPI <linux-acpi@vger.kernel.org>,
	Linux PM <linux-pm@vger.kernel.org>,
	Zhang Rui <rui.zhang@intel.com>,
	LKML <linux-kernel@vger.kernel.org>,
	Todd Brandt <todd.e.brandt@linux.intel.com>
Subject: Re: [PATCH v2] ACPI: EC: s2idle: Avoid premature returns from acpi_s2idle_wake()
Date: Mon, 11 May 2020 14:54:59 +0800	[thread overview]
Message-ID: <CAB4CAwfpO6=24tdVBtZ258hAE=sMyww-P9t1PC=BALhy3rHxSQ@mail.gmail.com> (raw)
In-Reply-To: <13031978.1nyG40egBz@kreacher>

On Sat, May 9, 2020 at 4:44 PM Rafael J. Wysocki <rjw@rjwysocki.net> wrote:
>
> From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
>
> If the EC GPE status is not set after checking all of the other GPEs,
> acpi_s2idle_wake() returns 'false', to indicate that the SCI event
> that has just triggered is not a system wakeup one, but it does that
> without canceling the pending wakeup and re-arming the SCI for system
> wakeup which is a mistake, because it may cause s2idle_loop() to busy
> spin until the next valid wakeup event.  [If that happens, the first
> spurious wakeup is still pending after acpi_s2idle_wake() has
> returned, so s2idle_enter() does nothing, acpi_s2idle_wake()
> is called again and it sees that the SCI has triggered, but no GPEs
> are active, so 'false' is returned again, and so on.]
>
> Fix that by moving all of the GPE checking logic from
> acpi_s2idle_wake() to acpi_ec_dispatch_gpe() and making the
> latter return 'true' only if a non-EC GPE has triggered and
> 'false' otherwise, which will cause acpi_s2idle_wake() to
> cancel the pending SCI wakeup and re-arm the SCI for system
> wakeup regardless of the EC GPE status.
>
> This also addresses a lockup observed on an Elitegroup EF20EA laptop
> after attempting to wake it up from suspend-to-idle by a key press.
>
> Fixes: d5406284ff80 ("ACPI: PM: s2idle: Refine active GPEs check")
> Link: https://bugzilla.kernel.org/show_bug.cgi?id=207603
> Reported-by: Todd Brandt <todd.e.brandt@linux.intel.com>
> Fixes: fdde0ff8590b ("ACPI: PM: s2idle: Prevent spurious SCIs from waking up the system")
> Link: https://lore.kernel.org/linux-acpi/CAB4CAwdqo7=MvyG_PE+PGVfeA17AHF5i5JucgaKqqMX6mjArbQ@mail.gmail.com/
> Reported-by: Chris Chiu <chiu@endlessm.com>
> Cc: 5.4+ <stable@vger.kernel.org> # 5.4+
> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> ---
Tested-by: Chris Chiu <chiu@endlessm.com>
>
> -> v2:
>    * Improve the changelog and add more tags.
>
> ---
>  drivers/acpi/ec.c       |   24 ++++++++++++++++--------
>  drivers/acpi/internal.h |    1 -
>  drivers/acpi/sleep.c    |   14 ++------------
>  3 files changed, 18 insertions(+), 21 deletions(-)
>
> Index: linux-pm/drivers/acpi/sleep.c
> ===================================================================
> --- linux-pm.orig/drivers/acpi/sleep.c
> +++ linux-pm/drivers/acpi/sleep.c
> @@ -1013,21 +1013,11 @@ static bool acpi_s2idle_wake(void)
>                 if (acpi_check_wakeup_handlers())
>                         return true;
>
> -               /*
> -                * If the status bit is set for any enabled GPE other than the
> -                * EC one, the wakeup is regarded as a genuine one.
> -                */
> -               if (acpi_ec_other_gpes_active())
> +               /* Check non-EC GPE wakeups and dispatch the EC GPE. */
> +               if (acpi_ec_dispatch_gpe())
>                         return true;
>
>                 /*
> -                * If the EC GPE status bit has not been set, the wakeup is
> -                * regarded as a spurious one.
> -                */
> -               if (!acpi_ec_dispatch_gpe())
> -                       return false;
> -
> -               /*
>                  * Cancel the wakeup and process all pending events in case
>                  * there are any wakeup ones in there.
>                  *
> Index: linux-pm/drivers/acpi/ec.c
> ===================================================================
> --- linux-pm.orig/drivers/acpi/ec.c
> +++ linux-pm/drivers/acpi/ec.c
> @@ -1994,23 +1994,31 @@ void acpi_ec_set_gpe_wake_mask(u8 action
>                 acpi_set_gpe_wake_mask(NULL, first_ec->gpe, action);
>  }
>
> -bool acpi_ec_other_gpes_active(void)
> -{
> -       return acpi_any_gpe_status_set(first_ec ? first_ec->gpe : U32_MAX);
> -}
> -
>  bool acpi_ec_dispatch_gpe(void)
>  {
>         u32 ret;
>
>         if (!first_ec)
> +               return acpi_any_gpe_status_set(U32_MAX);
> +
> +       /*
> +        * Report wakeup if the status bit is set for any enabled GPE other
> +        * than the EC one.
> +        */
> +       if (acpi_any_gpe_status_set(first_ec->gpe))
> +               return true;
> +
> +       if (ec_no_wakeup)
>                 return false;
>
> +       /*
> +        * Dispatch the EC GPE in-band, but do not report wakeup in any case
> +        * to allow the caller to process events properly after that.
> +        */
>         ret = acpi_dispatch_gpe(NULL, first_ec->gpe);
> -       if (ret == ACPI_INTERRUPT_HANDLED) {
> +       if (ret == ACPI_INTERRUPT_HANDLED)
>                 pm_pr_dbg("EC GPE dispatched\n");
> -               return true;
> -       }
> +
>         return false;
>  }
>  #endif /* CONFIG_PM_SLEEP */
> Index: linux-pm/drivers/acpi/internal.h
> ===================================================================
> --- linux-pm.orig/drivers/acpi/internal.h
> +++ linux-pm/drivers/acpi/internal.h
> @@ -202,7 +202,6 @@ void acpi_ec_remove_query_handler(struct
>
>  #ifdef CONFIG_PM_SLEEP
>  void acpi_ec_flush_work(void);
> -bool acpi_ec_other_gpes_active(void);
>  bool acpi_ec_dispatch_gpe(void);
>  #endif
>
>
>
>

      reply	other threads:[~2020-05-11  6:55 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-05-09  8:44 [PATCH v2] ACPI: EC: s2idle: Avoid premature returns from acpi_s2idle_wake() Rafael J. Wysocki
2020-05-11  6:54 ` Chris Chiu [this message]

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='CAB4CAwfpO6=24tdVBtZ258hAE=sMyww-P9t1PC=BALhy3rHxSQ@mail.gmail.com' \
    --to=chiu@endlessm.com \
    --cc=linux-acpi@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pm@vger.kernel.org \
    --cc=rjw@rjwysocki.net \
    --cc=rui.zhang@intel.com \
    --cc=todd.e.brandt@linux.intel.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.