From: Lv Zheng <lv.zheng@intel.com> To: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>, "Rafael J. Wysocki" <rjw@rjwysocki.net>, Len Brown <len.brown@intel.com> Cc: Lv Zheng <lv.zheng@intel.com>, Lv Zheng <zetalog@gmail.com>, linux-kernel@vger.kernel.org, linux-acpi@vger.kernel.org Subject: [PATCH v2 1/2] ACPI / EC: Add PM operations to tune polling mode efficiency Date: Fri, 29 Jul 2016 18:05:46 +0800 [thread overview] Message-ID: <62cf34b21f1c02cea3f0d92f87affb803e1e7c81.1469785918.git.lv.zheng@intel.com> (raw) In-Reply-To: <cover.1469785918.git.lv.zheng@intel.com> It is reported that on some platforms, resume speed is not fast. The cause is: in noirq stage, EC driver is working in polling mode, and each state machine advancement requires a context switch. The context switch is not necessary to the EC driver's polling mode. This patch implements PM hooks to automatically switch the driver to/from the busy polling mode to eliminate the overhead caused by the context switch. This finally contributes to the tuning result: acpi_pm_finish() execution time is improved from 192ms to 6ms. Signed-off-by: Lv Zheng <lv.zheng@intel.com> Reported-and-tested-by: Todd E Brandt <todd.e.brandt@linux.intel.com> --- drivers/acpi/ec.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++ drivers/acpi/internal.h | 2 ++ 2 files changed, 55 insertions(+) diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 907b450..7cdcdf6 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -1619,6 +1619,58 @@ error: return ret; } +#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 = + acpi_driver_data(to_acpi_device(dev)); + + acpi_ec_enter_noirq(ec); + return 0; +} + +static int acpi_ec_resume_noirq(struct device *dev) +{ + struct acpi_ec *ec = + acpi_driver_data(to_acpi_device(dev)); + + acpi_ec_leave_noirq(ec); + return 0; +} +#endif + +static const struct dev_pm_ops acpi_ec_pm = { + SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(acpi_ec_suspend_noirq, acpi_ec_resume_noirq) +}; + static int param_set_event_clearing(const char *val, struct kernel_param *kp) { int result = 0; @@ -1664,6 +1716,7 @@ static struct acpi_driver acpi_ec_driver = { .add = acpi_ec_add, .remove = acpi_ec_remove, }, + .drv.pm = &acpi_ec_pm, }; int __init acpi_ec_init(void) diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index 940218f..6996121 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h @@ -174,6 +174,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; }; extern struct acpi_ec *first_ec; -- 1.7.10
WARNING: multiple messages have this Message-ID (diff)
From: Lv Zheng <lv.zheng@intel.com> To: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>, "Rafael J. Wysocki" <rjw@rjwysocki.net>, Len Brown <len.brown@intel.com> Cc: Lv Zheng <lv.zheng@intel.com>, Lv Zheng <zetalog@gmail.com>, <linux-kernel@vger.kernel.org>, linux-acpi@vger.kernel.org Subject: [PATCH v2 1/2] ACPI / EC: Add PM operations to tune polling mode efficiency Date: Fri, 29 Jul 2016 18:05:46 +0800 [thread overview] Message-ID: <62cf34b21f1c02cea3f0d92f87affb803e1e7c81.1469785918.git.lv.zheng@intel.com> (raw) In-Reply-To: <cover.1469785918.git.lv.zheng@intel.com> It is reported that on some platforms, resume speed is not fast. The cause is: in noirq stage, EC driver is working in polling mode, and each state machine advancement requires a context switch. The context switch is not necessary to the EC driver's polling mode. This patch implements PM hooks to automatically switch the driver to/from the busy polling mode to eliminate the overhead caused by the context switch. This finally contributes to the tuning result: acpi_pm_finish() execution time is improved from 192ms to 6ms. Signed-off-by: Lv Zheng <lv.zheng@intel.com> Reported-and-tested-by: Todd E Brandt <todd.e.brandt@linux.intel.com> --- drivers/acpi/ec.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++ drivers/acpi/internal.h | 2 ++ 2 files changed, 55 insertions(+) diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 907b450..7cdcdf6 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -1619,6 +1619,58 @@ error: return ret; } +#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 = + acpi_driver_data(to_acpi_device(dev)); + + acpi_ec_enter_noirq(ec); + return 0; +} + +static int acpi_ec_resume_noirq(struct device *dev) +{ + struct acpi_ec *ec = + acpi_driver_data(to_acpi_device(dev)); + + acpi_ec_leave_noirq(ec); + return 0; +} +#endif + +static const struct dev_pm_ops acpi_ec_pm = { + SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(acpi_ec_suspend_noirq, acpi_ec_resume_noirq) +}; + static int param_set_event_clearing(const char *val, struct kernel_param *kp) { int result = 0; @@ -1664,6 +1716,7 @@ static struct acpi_driver acpi_ec_driver = { .add = acpi_ec_add, .remove = acpi_ec_remove, }, + .drv.pm = &acpi_ec_pm, }; int __init acpi_ec_init(void) diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index 940218f..6996121 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h @@ -174,6 +174,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; }; extern struct acpi_ec *first_ec; -- 1.7.10
next prev parent reply other threads:[~2016-07-29 10:05 UTC|newest] Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top 2016-07-21 9:36 [PATCH 1/2] ACPI / EC: Add PM operations to tune polling mode efficiency Lv Zheng 2016-07-21 9:36 ` Lv Zheng 2016-07-21 9:36 ` [PATCH 2/2] ACPI / EC: Add PM operations to block event handling Lv Zheng 2016-07-21 9:36 ` Lv Zheng 2016-07-26 0:11 ` Zheng, Lv 2016-07-29 10:05 ` [PATCH v2 0/2] ACPI / EC: Tune suspend/resume speed using PM operations Lv Zheng 2016-07-29 10:05 ` Lv Zheng 2016-07-29 10:05 ` Lv Zheng [this message] 2016-07-29 10:05 ` [PATCH v2 1/2] ACPI / EC: Add PM operations to tune polling mode efficiency Lv Zheng 2016-07-29 10:05 ` [PATCH v2 2/2] ACPI / EC: Add PM operations to block event handling Lv Zheng 2016-07-29 10:05 ` Lv Zheng 2016-08-03 1:03 ` Zheng, Lv 2016-08-03 1:07 ` [PATCH v3] ACPI / EC: Add PM operations to tune polling mode efficiency for suspend/resume noirq stage Lv Zheng 2016-08-03 8:01 ` [PATCH v3 0/5] ACPI / EC: Move the event handling out of the " Lv Zheng 2016-08-03 8:01 ` Lv Zheng 2016-08-03 8:01 ` [PATCH v3 1/5] ACPI / EC: Add EC_FLAGS_QUERY_ENABLED to reveal a hidden logic Lv Zheng 2016-08-03 8:01 ` Lv Zheng 2016-08-03 8:01 ` [PATCH v3 2/5] ACPI / EC: Fix an issue that SCI_EVT cannot be detected after event is enabled Lv Zheng 2016-08-03 8:01 ` Lv Zheng 2016-08-03 8:01 ` [PATCH v3 3/5] ACPI / EC: Add PM operations to improve event handling for resume process Lv Zheng 2016-08-03 8:01 ` Lv Zheng 2016-08-03 8:01 ` [PATCH v3 4/5] ACPI / EC: Add PM operations to improve event handling for suspend process Lv Zheng 2016-08-03 8:01 ` Lv Zheng 2016-08-03 8:01 ` [PATCH v3 5/5] ACPI / EC: Enable event freeze mode " Lv Zheng 2016-08-03 8:01 ` Lv Zheng 2016-09-12 21:59 ` [PATCH v3 0/5] ACPI / EC: Move the event handling out of the noirq stage 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=62cf34b21f1c02cea3f0d92f87affb803e1e7c81.1469785918.git.lv.zheng@intel.com \ --to=lv.zheng@intel.com \ --cc=len.brown@intel.com \ --cc=linux-acpi@vger.kernel.org \ --cc=linux-kernel@vger.kernel.org \ --cc=rafael.j.wysocki@intel.com \ --cc=rjw@rjwysocki.net \ --cc=zetalog@gmail.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: linkBe 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.