Patch "ACPI / EC: Work around method reentrancy limit in ACPICA for _Qxx ACPI / EC: Fix an issue caused by the serialized _Qxx evaluations" has been added to the 4.4-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
ACPI / EC: Work around method reentrancy limit in ACPICA for _Qxx
ACPI / EC: Fix an issue caused by the serialized _Qxx evaluations
to the 4.4-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-work-around-method-reentrancy-limit-in-acpica-for-_qxx.patch
and it can be found in the queue-4.4 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
e1191bd4f62d9086a1a47adc286e7fcffc1fa55cMon Sep 17 00:00:00 2001
From: Lv Zheng <[email protected]>
Date: Wed, 3 Aug 2016 09:00:14 +0800
Subject: ACPI / EC: Work around method reentrancy limit in ACPICA for _Qxx
From: Lv Zheng <[email protected]>
commit e1191bd4f62d9086a1a47adc286e7fcffc1fa55c upstream.
A regression is caused by the following commit:
Commit: 02b771b64b73226052d6e731a0987db3b47281e9
Subject: ACPI / EC: Fix an issue caused by the serialized _Qxx evaluations
In this commit, using system workqueue causes that the maximum parallel executions of _Qxx can exceed 255. This violates the method reentrancy limit in ACPICA and generates the following error log:
ACPI Error: Method reached maximum reentrancy limit (255) (20150818/dsmethod-341)
This patch creates a seperate workqueue and limits the number of parallel _Qxx evaluations down to a configurable value (can be tuned against number of online CPUs).
Since EC events are handled after driver probe, we can create the workqueue in acpi_ec_init().
--- drivers/acpi/ec.c | 41 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 4 deletions(-)
drivers/acpi/ec.c +37 -4
@@ -101,6 +101,7 @@ enum ec_command {#define ACPI_EC_UDELAY_POLL 550/* Wait 1ms for EC transaction polling */ #define ACPI_EC_CLEAR_MAX 100/* Maximum number of events to query * when trying to clear the EC */ +#define ACPI_EC_MAX_QUERIES 16/* Maximum number of parallel queries */ enum {EC_FLAGS_QUERY_PENDING ,/* Query is pending */
@@ -121,6 +122,10 @@ static unsigned int ec_delay __read_mostmodule_param (ec_delay, uint,0644 );MODULE_PARM_DESC (ec_delay,"Timeout(ms) waited until an EC command completes" ); +static unsigned int ec_max_queries__read_mostly =ACPI_EC_MAX_QUERIES ; +module_param (ec_max_queries, uint,0644 ); +MODULE_PARM_DESC (ec_max_queries,"Maximum parallel _Qxx evaluations" ); +static bool ec_busy_polling__read_mostly ;module_param (ec_busy_polling, bool,0644 );MODULE_PARM_DESC (ec_busy_polling,"Use busy polling to advance EC transaction" );
@@ -174,6 +179,7 @@ static void acpi_ec_event_processor(strustruct acpi_ec *boot_ec, *first_ec;EXPORT_SYMBOL (first_ec); +static struct workqueue_struct *ec_query_wq;static int EC_FLAGS_VALIDATE_ECDT ;/* ASUStec ECDTs need to be validated */ static int EC_FLAGS_SKIP_DSDT_SCAN ;/* Not all BIOS survive early DSDT scan */
@@ -1097,7 +1103,7 @@ static int acpi_ec_query(struct acpi_ec* work queue execution. */ ec_dbg_evt ("Query(0x%02x) scheduled" , value); -if (!schedule_work (&q->work)) { +if (!queue_work (ec_query_wq, &q->work)) {ec_dbg_evt ("Query(0x%02x) overlapped" , value); result = -EBUSY ; }
@@ -1657,15 +1663,41 @@ static struct acpi_driver acpi_ec_driver }, }; +static inline int acpi_ec_query_init (void ) +{ +if (!ec_query_wq) { + ec_query_wq =alloc_workqueue ("kec_query" ,0 , + ec_max_queries); +if (!ec_query_wq) +return -ENODEV ; + } +return 0 ; +} + +static inline void acpi_ec_query_exit (void ) +{ +if (ec_query_wq) { +destroy_workqueue (ec_query_wq); + ec_query_wq =NULL ; + } +} +int __init acpi_ec_init (void ) { -int result =0 ; +int result; +/* register workqueue for _Qxx evaluations */ + result =acpi_ec_query_init (); +if (result) + goto err_exit;/* Now register the driver for the EC */ result =acpi_bus_register_driver (&acpi_ec_driver); -if (result <0 ) -return -ENODEV ; +if (result) + goto err_exit; +err_exit: +if (result) +acpi_ec_query_exit ();return result; }
@@ -1675,5 +1707,6 @@ static void __exit acpi_ec_exit(void) {acpi_bus_unregister_driver (&acpi_ec_driver); +acpi_ec_query_exit (); }#endif /* 0 */
Patches currently in stable-queue which might be from [email protected] are
queue-4.4/acpi-ec-work-around-method-reentrancy-limit-in-acpica-for-_qxx.patch