From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail.linuxfoundation.org ([140.211.169.12]:58648 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1761985AbdDSMeT (ORCPT ); Wed, 19 Apr 2017 08:34:19 -0400 Subject: Patch "ACPI / EC: Use busy polling mode when GPE is not enabled" has been added to the 4.9-stable tree To: lv.zheng@intel.com, ben@decadent.org.uk, gregkh@linuxfoundation.org, jakobus.schurz@gmail.com, rafael.j.wysocki@intel.com, yu.c.chen@intel.com Cc: , From: Date: Wed, 19 Apr 2017 14:34:09 +0200 Message-ID: <1492605249169232@kroah.com> MIME-Version: 1.0 Content-Type: text/plain; charset=ANSI_X3.4-1968 Content-Transfer-Encoding: 8bit Sender: stable-owner@vger.kernel.org List-ID: This is a note to let you know that I've just added the patch titled ACPI / EC: Use busy polling mode when GPE is not enabled to the 4.9-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: acpi-ec-use-busy-polling-mode-when-gpe-is-not-enabled.patch and it can be found in the queue-4.9 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let know about it. >>From c3a696b6e8f8f75f9f75e556a9f9f6472eae2655 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Fri, 20 Jan 2017 16:42:48 +0800 Subject: ACPI / EC: Use busy polling mode when GPE is not enabled From: Lv Zheng commit c3a696b6e8f8f75f9f75e556a9f9f6472eae2655 upstream. When GPE is not enabled, it is not efficient to use the wait polling mode as it introduces an unexpected scheduler delay. So before the GPE handler is installed, this patch uses busy polling mode for all EC(s) and the logic can be applied to non boot EC(s) during the suspend/resume process. Link: https://bugzilla.kernel.org/show_bug.cgi?id=191561 Tested-by: Jakobus Schurz Tested-by: Chen Yu Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki Cc: Ben Hutchings Signed-off-by: Greg Kroah-Hartman --- drivers/acpi/ec.c | 62 +++++++++++++++++++++++------------------------- drivers/acpi/internal.h | 4 +-- 2 files changed, 32 insertions(+), 34 deletions(-) --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -729,12 +729,12 @@ static void start_transaction(struct acp static int ec_guard(struct acpi_ec *ec) { - unsigned long guard = usecs_to_jiffies(ec_polling_guard); + unsigned long guard = usecs_to_jiffies(ec->polling_guard); unsigned long timeout = ec->timestamp + guard; /* Ensure guarding period before polling EC status */ do { - if (ec_busy_polling) { + if (ec->busy_polling) { /* Perform busy polling */ if (ec_transaction_completed(ec)) return 0; @@ -998,6 +998,28 @@ static void acpi_ec_stop(struct acpi_ec spin_unlock_irqrestore(&ec->lock, flags); } +static void acpi_ec_enter_noirq(struct acpi_ec *ec) +{ + unsigned long flags; + + spin_lock_irqsave(&ec->lock, flags); + ec->busy_polling = true; + ec->polling_guard = 0; + ec_log_drv("interrupt blocked"); + spin_unlock_irqrestore(&ec->lock, flags); +} + +static void acpi_ec_leave_noirq(struct acpi_ec *ec) +{ + unsigned long flags; + + spin_lock_irqsave(&ec->lock, flags); + ec->busy_polling = ec_busy_polling; + ec->polling_guard = ec_polling_guard; + ec_log_drv("interrupt unblocked"); + spin_unlock_irqrestore(&ec->lock, flags); +} + void acpi_ec_block_transactions(void) { struct acpi_ec *ec = first_ec; @@ -1278,7 +1300,7 @@ acpi_ec_space_handler(u32 function, acpi if (function != ACPI_READ && function != ACPI_WRITE) return AE_BAD_PARAMETER; - if (ec_busy_polling || bits > 8) + if (ec->busy_polling || bits > 8) acpi_ec_burst_enable(ec); for (i = 0; i < bytes; ++i, ++address, ++value) @@ -1286,7 +1308,7 @@ acpi_ec_space_handler(u32 function, acpi acpi_ec_read(ec, address, value) : acpi_ec_write(ec, address, *value); - if (ec_busy_polling || bits > 8) + if (ec->busy_polling || bits > 8) acpi_ec_burst_disable(ec); switch (result) { @@ -1329,6 +1351,8 @@ static struct acpi_ec *acpi_ec_alloc(voi spin_lock_init(&ec->lock); INIT_WORK(&ec->work, acpi_ec_event_handler); ec->timestamp = jiffies; + ec->busy_polling = true; + ec->polling_guard = 0; return ec; } @@ -1390,6 +1414,7 @@ static int ec_install_handlers(struct ac acpi_ec_start(ec, false); if (!test_bit(EC_FLAGS_EC_HANDLER_INSTALLED, &ec->flags)) { + acpi_ec_enter_noirq(ec); status = acpi_install_address_space_handler(ec->handle, ACPI_ADR_SPACE_EC, &acpi_ec_space_handler, @@ -1429,6 +1454,7 @@ static int ec_install_handlers(struct ac /* This is not fatal as we can poll EC events */ if (ACPI_SUCCESS(status)) { set_bit(EC_FLAGS_GPE_HANDLER_INSTALLED, &ec->flags); + acpi_ec_leave_noirq(ec); if (test_bit(EC_FLAGS_STARTED, &ec->flags) && ec->reference_count >= 1) acpi_ec_enable_gpe(ec, true); @@ -1839,34 +1865,6 @@ error: } #ifdef CONFIG_PM_SLEEP -static void acpi_ec_enter_noirq(struct acpi_ec *ec) -{ - unsigned long flags; - - if (ec == first_ec) { - spin_lock_irqsave(&ec->lock, flags); - ec->saved_busy_polling = ec_busy_polling; - ec->saved_polling_guard = ec_polling_guard; - ec_busy_polling = true; - ec_polling_guard = 0; - ec_log_drv("interrupt blocked"); - spin_unlock_irqrestore(&ec->lock, flags); - } -} - -static void acpi_ec_leave_noirq(struct acpi_ec *ec) -{ - unsigned long flags; - - if (ec == first_ec) { - spin_lock_irqsave(&ec->lock, flags); - ec_busy_polling = ec->saved_busy_polling; - ec_polling_guard = ec->saved_polling_guard; - ec_log_drv("interrupt unblocked"); - spin_unlock_irqrestore(&ec->lock, flags); - } -} - static int acpi_ec_suspend_noirq(struct device *dev) { struct acpi_ec *ec = --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h @@ -172,8 +172,8 @@ struct acpi_ec { struct work_struct work; unsigned long timestamp; unsigned long nr_pending_queries; - bool saved_busy_polling; - unsigned int saved_polling_guard; + bool busy_polling; + unsigned int polling_guard; }; extern struct acpi_ec *first_ec; Patches currently in stable-queue which might be from lv.zheng@intel.com are queue-4.9/acpi-ec-use-busy-polling-mode-when-gpe-is-not-enabled.patch