All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] ACPI / EC: Fix a regression by reducing parallel _Qxx evaluations
@ 2016-07-27  8:32 Lv Zheng
  2016-07-29  3:58 ` Zheng, Lv
  2016-08-03  1:00 ` [PATCH v2] " Lv Zheng
  0 siblings, 2 replies; 5+ messages in thread
From: Lv Zheng @ 2016-07-27  8:32 UTC (permalink / raw)
  To: Rafael J. Wysocki, Rafael J. Wysocki, Len Brown
  Cc: Lv Zheng, Lv Zheng, linux-acpi

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().

Fixes: 02b771b64b73 (ACPI / EC: Fix an issue caused by the serialized _Qxx evaluations)
Cc: <stable@vger.kernel.org> # 4.3+
Reported-and-tested-by: Helen Buus <ubuntu@hbuus.com>
Signed-off-by: Lv Zheng <lv.zheng@intel.com>
---
 drivers/acpi/ec.c |   13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 999a109..907b450 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -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_mostly = ACPI_EC_DELAY;
 module_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(struct work_struct *work);
 
 struct acpi_ec *boot_ec, *first_ec;
 EXPORT_SYMBOL(first_ec);
+static struct workqueue_struct *ec_query_wq;
 
 static int EC_FLAGS_CLEAR_ON_RESUME; /* Needs acpi_ec_clear() on boot/resume */
 static int EC_FLAGS_QUERY_HANDSHAKE; /* Needs QR_EC issued when SCI_EVT set */
@@ -1098,7 +1104,7 @@ static int acpi_ec_query(struct acpi_ec *ec, u8 *data)
 	 * 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;
 	}
@@ -1664,6 +1670,10 @@ int __init acpi_ec_init(void)
 {
 	int result = 0;
 
+	ec_query_wq = alloc_workqueue("kec_query", 0, ec_max_queries);
+	if (!ec_query_wq)
+		return -ENODEV;
+
 	/* Now register the driver for the EC */
 	result = acpi_bus_register_driver(&acpi_ec_driver);
 	if (result < 0)
@@ -1678,5 +1688,6 @@ static void __exit acpi_ec_exit(void)
 {
 
 	acpi_bus_unregister_driver(&acpi_ec_driver);
+	destroy_workqueue(ec_query_wq);
 }
 #endif	/* 0 */
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* RE: [PATCH] ACPI / EC: Fix a regression by reducing parallel _Qxx evaluations
  2016-07-27  8:32 [PATCH] ACPI / EC: Fix a regression by reducing parallel _Qxx evaluations Lv Zheng
@ 2016-07-29  3:58 ` Zheng, Lv
  2016-08-02  0:54   ` Rafael J. Wysocki
  2016-08-03  1:00 ` [PATCH v2] " Lv Zheng
  1 sibling, 1 reply; 5+ messages in thread
From: Zheng, Lv @ 2016-07-29  3:58 UTC (permalink / raw)
  To: Wysocki, Rafael J, Rafael J. Wysocki, Brown, Len; +Cc: Lv Zheng, linux-acpi

Hi, Rafael

> From: Zheng, Lv
> Subject: [PATCH] ACPI / EC: Fix a regression by reducing parallel _Qxx
> evaluations
> 
> 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().
> 
> Fixes: 02b771b64b73 (ACPI / EC: Fix an issue caused by the serialized _Qxx
> evaluations)
> Cc: <stable@vger.kernel.org> # 4.3+
> Reported-and-tested-by: Helen Buus <ubuntu@hbuus.com>
[Lv Zheng] 
I'm sorry that I forgot to mention the bug link.
It's actually recorded in kernel Bugzilla.
The bug can be found here:
Link: https://bugzilla.kernel.org/show_bug.cgi?id=135691
Hope you can help to add this useful information if this patch is acceptable.

Best regards
-Lv

> Signed-off-by: Lv Zheng <lv.zheng@intel.com>
> ---
>  drivers/acpi/ec.c |   13 ++++++++++++-
>  1 file changed, 12 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
> index 999a109..907b450 100644
> --- a/drivers/acpi/ec.c
> +++ b/drivers/acpi/ec.c
> @@ -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_mostly =
> ACPI_EC_DELAY;
>  module_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(struct
> work_struct *work);
> 
>  struct acpi_ec *boot_ec, *first_ec;
>  EXPORT_SYMBOL(first_ec);
> +static struct workqueue_struct *ec_query_wq;
> 
>  static int EC_FLAGS_CLEAR_ON_RESUME; /* Needs acpi_ec_clear() on
> boot/resume */
>  static int EC_FLAGS_QUERY_HANDSHAKE; /* Needs QR_EC issued when
> SCI_EVT set */
> @@ -1098,7 +1104,7 @@ static int acpi_ec_query(struct acpi_ec *ec, u8
> *data)
>  	 * 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;
>  	}
> @@ -1664,6 +1670,10 @@ int __init acpi_ec_init(void)
>  {
>  	int result = 0;
> 
> +	ec_query_wq = alloc_workqueue("kec_query", 0, ec_max_queries);
> +	if (!ec_query_wq)
> +		return -ENODEV;
> +
>  	/* Now register the driver for the EC */
>  	result = acpi_bus_register_driver(&acpi_ec_driver);
>  	if (result < 0)
> @@ -1678,5 +1688,6 @@ static void __exit acpi_ec_exit(void)
>  {
> 
>  	acpi_bus_unregister_driver(&acpi_ec_driver);
> +	destroy_workqueue(ec_query_wq);
>  }
>  #endif	/* 0 */
> --
> 1.7.10


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] ACPI / EC: Fix a regression by reducing parallel _Qxx evaluations
  2016-07-29  3:58 ` Zheng, Lv
@ 2016-08-02  0:54   ` Rafael J. Wysocki
  2016-08-02 11:08     ` Zheng, Lv
  0 siblings, 1 reply; 5+ messages in thread
From: Rafael J. Wysocki @ 2016-08-02  0:54 UTC (permalink / raw)
  To: Zheng, Lv; +Cc: Wysocki, Rafael J, Brown, Len, Lv Zheng, linux-acpi

On Friday, July 29, 2016 03:58:20 AM Zheng, Lv wrote:
> Hi, Rafael
> 
> > From: Zheng, Lv
> > Subject: [PATCH] ACPI / EC: Fix a regression by reducing parallel _Qxx
> > evaluations
> > 
> > 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().
> > 
> > Fixes: 02b771b64b73 (ACPI / EC: Fix an issue caused by the serialized _Qxx
> > evaluations)
> > Cc: <stable@vger.kernel.org> # 4.3+
> > Reported-and-tested-by: Helen Buus <ubuntu@hbuus.com>
> [Lv Zheng] 
> I'm sorry that I forgot to mention the bug link.
> It's actually recorded in kernel Bugzilla.
> The bug can be found here:
> Link: https://bugzilla.kernel.org/show_bug.cgi?id=135691
> Hope you can help to add this useful information if this patch is acceptable.

I did that, but due to the problem reported against this patch
(https://patchwork.kernel.org/patch/9252645/), I'm going to drop it from
linux-next and I'll be waiting for an update with that problem addressed.

Thanks,
Rafael


^ permalink raw reply	[flat|nested] 5+ messages in thread

* RE: [PATCH] ACPI / EC: Fix a regression by reducing parallel _Qxx evaluations
  2016-08-02  0:54   ` Rafael J. Wysocki
@ 2016-08-02 11:08     ` Zheng, Lv
  0 siblings, 0 replies; 5+ messages in thread
From: Zheng, Lv @ 2016-08-02 11:08 UTC (permalink / raw)
  To: Rafael J. Wysocki; +Cc: Wysocki, Rafael J, Brown, Len, Lv Zheng, linux-acpi

Hi, Rafael

> From: Rafael J. Wysocki [mailto:rjw@rjwysocki.net]
> Subject: Re: [PATCH] ACPI / EC: Fix a regression by reducing parallel _Qxx
> evaluations
> 
> On Friday, July 29, 2016 03:58:20 AM Zheng, Lv wrote:
> > Hi, Rafael
> >
> > > From: Zheng, Lv
> > > Subject: [PATCH] ACPI / EC: Fix a regression by reducing parallel _Qxx
> > > evaluations
> > >
> > > 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().
> > >
> > > Fixes: 02b771b64b73 (ACPI / EC: Fix an issue caused by the serialized
> _Qxx
> > > evaluations)
> > > Cc: <stable@vger.kernel.org> # 4.3+
> > > Reported-and-tested-by: Helen Buus <ubuntu@hbuus.com>
> > [Lv Zheng]
> > I'm sorry that I forgot to mention the bug link.
> > It's actually recorded in kernel Bugzilla.
> > The bug can be found here:
> > Link: https://bugzilla.kernel.org/show_bug.cgi?id=135691
> > Hope you can help to add this useful information if this patch is
> acceptable.
> 
> I did that, but due to the problem reported against this patch
> (https://patchwork.kernel.org/patch/9252645/), I'm going to drop it from
> linux-next and I'll be waiting for an update with that problem addressed.

[Lv Zheng] 
OK, I'll re-send an update of this patch.
Sorry for the problem.

Thanks
Lv

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v2] ACPI / EC: Fix a regression by reducing parallel _Qxx evaluations
  2016-07-27  8:32 [PATCH] ACPI / EC: Fix a regression by reducing parallel _Qxx evaluations Lv Zheng
  2016-07-29  3:58 ` Zheng, Lv
@ 2016-08-03  1:00 ` Lv Zheng
  1 sibling, 0 replies; 5+ messages in thread
From: Lv Zheng @ 2016-08-03  1:00 UTC (permalink / raw)
  To: Rafael J. Wysocki, Rafael J. Wysocki, Len Brown
  Cc: Lv Zheng, Lv Zheng, linux-acpi, Wei Yongjun

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().

Fixes: 02b771b64b73 (ACPI / EC: Fix an issue caused by the serialized _Qxx evaluations)
Cc: <stable@vger.kernel.org> # 4.3+
Reported-and-tested-by: Helen Buus <ubuntu@hbuus.com>
Signed-off-by: Lv Zheng <lv.zheng@intel.com>
Cc: Wei Yongjun <weiyj.lk@gmail.com>
---
 drivers/acpi/ec.c |   41 +++++++++++++++++++++++++++++++++++++----
 1 file changed, 37 insertions(+), 4 deletions(-)

diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 999a109..e7bd57c 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -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_mostly = ACPI_EC_DELAY;
 module_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(struct work_struct *work);
 
 struct acpi_ec *boot_ec, *first_ec;
 EXPORT_SYMBOL(first_ec);
+static struct workqueue_struct *ec_query_wq;
 
 static int EC_FLAGS_CLEAR_ON_RESUME; /* Needs acpi_ec_clear() on boot/resume */
 static int EC_FLAGS_QUERY_HANDSHAKE; /* Needs QR_EC issued when SCI_EVT set */
@@ -1098,7 +1104,7 @@ static int acpi_ec_query(struct acpi_ec *ec, u8 *data)
 	 * 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;
 	}
@@ -1660,15 +1666,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;
 }
 
@@ -1678,5 +1710,6 @@ static void __exit acpi_ec_exit(void)
 {
 
 	acpi_bus_unregister_driver(&acpi_ec_driver);
+	acpi_ec_query_exit();
 }
 #endif	/* 0 */
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2016-08-03  1:00 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-07-27  8:32 [PATCH] ACPI / EC: Fix a regression by reducing parallel _Qxx evaluations Lv Zheng
2016-07-29  3:58 ` Zheng, Lv
2016-08-02  0:54   ` Rafael J. Wysocki
2016-08-02 11:08     ` Zheng, Lv
2016-08-03  1:00 ` [PATCH v2] " Lv Zheng

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.