All of lore.kernel.org
 help / color / mirror / Atom feed
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 3/3] ACPI / sysfs: Provide quirk mechanism to prevent GPE flooding
Date: Mon, 16 May 2016 17:11:24 +0800	[thread overview]
Message-ID: <c6808078a092fbf990d535cc359b734108ae5d6b.1463389640.git.lv.zheng@intel.com> (raw)
In-Reply-To: <cover.1463389639.git.lv.zheng@intel.com>

Sometimes, the users may require a quirk to be provided from ACPI subsystem
core to prevent a GPE from flooding. Normally, if a GPE cannot be
dispatched, ACPICA core automatically prevents the GPE from firing. But
there are cases the GPE is dispatched by _Lxx/_Exx provided via AML table,
and OSPM is lacking of the knowledge to get _Lxx/_Exx correctly executed to
handle the GPE, thus the GPE flooding may still occur.

This patch provides a quirk mechanism to stop this kind of GPE flooding.

Link: https://bugzilla.kernel.org/show_bug.cgi?id=53071
Link: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/887793
Signed-off-by: Lv Zheng <lv.zheng@intel.com>
---
 drivers/acpi/internal.h |    1 +
 drivers/acpi/scan.c     |    1 +
 drivers/acpi/sleep.c    |    2 ++
 drivers/acpi/sysfs.c    |   56 +++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 60 insertions(+)

diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index 9bb0773..d0f1744 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -37,6 +37,7 @@ void acpi_amba_init(void);
 static inline void acpi_amba_init(void) {}
 #endif
 int acpi_sysfs_init(void);
+void acpi_gpe_apply_blocked_gpes(void);
 void acpi_container_init(void);
 void acpi_memory_hotplug_init(void);
 #ifdef	CONFIG_ACPI_HOTPLUG_IOAPIC
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 5f28cf7..5ff366c 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1958,6 +1958,7 @@ int __init acpi_scan_init(void)
 		}
 	}
 
+	acpi_gpe_apply_blocked_gpes();
 	acpi_update_all_gpes();
 
  out:
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
index d00544c..daba3ba 100644
--- a/drivers/acpi/sleep.c
+++ b/drivers/acpi/sleep.c
@@ -414,6 +414,7 @@ static void acpi_pm_finish(void)
 		acpi_state);
 	acpi_disable_wakeup_devices(acpi_state);
 	acpi_leave_sleep_state(acpi_state);
+	acpi_gpe_apply_blocked_gpes();
 
 	/* reset firmware waking vector */
 	acpi_set_waking_vector(0);
@@ -774,6 +775,7 @@ static void acpi_pm_thaw(void)
 {
 	acpi_ec_unblock_transactions();
 	acpi_enable_all_runtime_gpes();
+	acpi_gpe_apply_blocked_gpes();
 }
 
 static const struct platform_hibernation_ops acpi_hibernation_ops = {
diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c
index 7f33c90..a2fb524 100644
--- a/drivers/acpi/sysfs.c
+++ b/drivers/acpi/sysfs.c
@@ -715,6 +715,62 @@ end:
 	return result ? result : size;
 }
 
+/*
+ * A Quirk Mechanism for GPE Flooding Prevention:
+ *
+ * Quirks may be needed to prevent GPE flooding on a specific GPE. The
+ * flooding typically cannot be detected and automatically prevented by
+ * ACPI_GPE_DISPATCH_NONE check because there is a _Lxx/_Exx prepared in
+ * the AML tables. This normally indicates a feature gap in Linux, thus
+ * instead of providing endless quirk tables, we provide a boot parameter
+ * for those who want this quirk. For example, if the users want to prevent
+ * the GPE flooding for GPE 00, they need to specify the following boot
+ * parameter:
+ *   acpi.block_gpe=0x00
+ * The blocking status can be modified by the following runtime controlling
+ * interface:
+ *   echo unblock > /sys/firmware/acpi/interrupts/gpe00
+ */
+
+/*
+ * Currently, the GPE flooding prevention only supports to block the GPEs
+ * numbered from 00 to 63.
+ */
+#define ACPI_BLOCKABLE_GPE_MAX	64
+
+static u64 acpi_blocked_gpes;
+
+static int __init acpi_gpe_set_blocked_gpes(char *val)
+{
+	u8 gpe;
+
+	if (kstrtou8(val, 0, &gpe) || gpe > ACPI_BLOCKABLE_GPE_MAX)
+		return -EINVAL;
+	acpi_blocked_gpes |= ((u64)1<<gpe);
+
+	return 1;
+}
+__setup("acpi_block_gpe=", acpi_gpe_set_blocked_gpes);
+
+void acpi_gpe_apply_blocked_gpes(void)
+{
+	acpi_handle handle;
+	acpi_status status;
+	u8 gpe;
+
+	for (gpe = 0;
+	     gpe < min_t(u8, ACPI_BLOCKABLE_GPE_MAX, acpi_current_gpe_count);
+	     gpe++) {
+		if (acpi_blocked_gpes & ((u64)1<<gpe)) {
+			status = acpi_get_gpe_device(gpe, &handle);
+			if (ACPI_SUCCESS(status)) {
+				pr_info("Blocking GPE 0x%x.\n", gpe);
+				(void)acpi_block_gpe(handle, gpe);
+			}
+		}
+	}
+}
+
 void acpi_irq_stats_init(void)
 {
 	acpi_status status;
-- 
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 3/3] ACPI / sysfs: Provide quirk mechanism to prevent GPE flooding
Date: Mon, 16 May 2016 17:11:24 +0800	[thread overview]
Message-ID: <c6808078a092fbf990d535cc359b734108ae5d6b.1463389640.git.lv.zheng@intel.com> (raw)
In-Reply-To: <cover.1463389639.git.lv.zheng@intel.com>

Sometimes, the users may require a quirk to be provided from ACPI subsystem
core to prevent a GPE from flooding. Normally, if a GPE cannot be
dispatched, ACPICA core automatically prevents the GPE from firing. But
there are cases the GPE is dispatched by _Lxx/_Exx provided via AML table,
and OSPM is lacking of the knowledge to get _Lxx/_Exx correctly executed to
handle the GPE, thus the GPE flooding may still occur.

This patch provides a quirk mechanism to stop this kind of GPE flooding.

Link: https://bugzilla.kernel.org/show_bug.cgi?id=53071
Link: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/887793
Signed-off-by: Lv Zheng <lv.zheng@intel.com>
---
 drivers/acpi/internal.h |    1 +
 drivers/acpi/scan.c     |    1 +
 drivers/acpi/sleep.c    |    2 ++
 drivers/acpi/sysfs.c    |   56 +++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 60 insertions(+)

diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index 9bb0773..d0f1744 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -37,6 +37,7 @@ void acpi_amba_init(void);
 static inline void acpi_amba_init(void) {}
 #endif
 int acpi_sysfs_init(void);
+void acpi_gpe_apply_blocked_gpes(void);
 void acpi_container_init(void);
 void acpi_memory_hotplug_init(void);
 #ifdef	CONFIG_ACPI_HOTPLUG_IOAPIC
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 5f28cf7..5ff366c 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1958,6 +1958,7 @@ int __init acpi_scan_init(void)
 		}
 	}
 
+	acpi_gpe_apply_blocked_gpes();
 	acpi_update_all_gpes();
 
  out:
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
index d00544c..daba3ba 100644
--- a/drivers/acpi/sleep.c
+++ b/drivers/acpi/sleep.c
@@ -414,6 +414,7 @@ static void acpi_pm_finish(void)
 		acpi_state);
 	acpi_disable_wakeup_devices(acpi_state);
 	acpi_leave_sleep_state(acpi_state);
+	acpi_gpe_apply_blocked_gpes();
 
 	/* reset firmware waking vector */
 	acpi_set_waking_vector(0);
@@ -774,6 +775,7 @@ static void acpi_pm_thaw(void)
 {
 	acpi_ec_unblock_transactions();
 	acpi_enable_all_runtime_gpes();
+	acpi_gpe_apply_blocked_gpes();
 }
 
 static const struct platform_hibernation_ops acpi_hibernation_ops = {
diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c
index 7f33c90..a2fb524 100644
--- a/drivers/acpi/sysfs.c
+++ b/drivers/acpi/sysfs.c
@@ -715,6 +715,62 @@ end:
 	return result ? result : size;
 }
 
+/*
+ * A Quirk Mechanism for GPE Flooding Prevention:
+ *
+ * Quirks may be needed to prevent GPE flooding on a specific GPE. The
+ * flooding typically cannot be detected and automatically prevented by
+ * ACPI_GPE_DISPATCH_NONE check because there is a _Lxx/_Exx prepared in
+ * the AML tables. This normally indicates a feature gap in Linux, thus
+ * instead of providing endless quirk tables, we provide a boot parameter
+ * for those who want this quirk. For example, if the users want to prevent
+ * the GPE flooding for GPE 00, they need to specify the following boot
+ * parameter:
+ *   acpi.block_gpe=0x00
+ * The blocking status can be modified by the following runtime controlling
+ * interface:
+ *   echo unblock > /sys/firmware/acpi/interrupts/gpe00
+ */
+
+/*
+ * Currently, the GPE flooding prevention only supports to block the GPEs
+ * numbered from 00 to 63.
+ */
+#define ACPI_BLOCKABLE_GPE_MAX	64
+
+static u64 acpi_blocked_gpes;
+
+static int __init acpi_gpe_set_blocked_gpes(char *val)
+{
+	u8 gpe;
+
+	if (kstrtou8(val, 0, &gpe) || gpe > ACPI_BLOCKABLE_GPE_MAX)
+		return -EINVAL;
+	acpi_blocked_gpes |= ((u64)1<<gpe);
+
+	return 1;
+}
+__setup("acpi_block_gpe=", acpi_gpe_set_blocked_gpes);
+
+void acpi_gpe_apply_blocked_gpes(void)
+{
+	acpi_handle handle;
+	acpi_status status;
+	u8 gpe;
+
+	for (gpe = 0;
+	     gpe < min_t(u8, ACPI_BLOCKABLE_GPE_MAX, acpi_current_gpe_count);
+	     gpe++) {
+		if (acpi_blocked_gpes & ((u64)1<<gpe)) {
+			status = acpi_get_gpe_device(gpe, &handle);
+			if (ACPI_SUCCESS(status)) {
+				pr_info("Blocking GPE 0x%x.\n", gpe);
+				(void)acpi_block_gpe(handle, gpe);
+			}
+		}
+	}
+}
+
 void acpi_irq_stats_init(void)
 {
 	acpi_status status;
-- 
1.7.10

  parent reply	other threads:[~2016-05-16  9:11 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <cover.1463389639.git.lv.zheng@intel.com>
2016-05-16  9:11 ` [PATCH 1/3] ACPICA: Events: Introduce acpi_block_gpe()/acpi_unblock_gpe()/acpi_control_gpe_handling() to allow administrative GPE enabling/disabling Lv Zheng
2016-05-16  9:11   ` Lv Zheng
2016-06-07 22:01   ` Rafael J. Wysocki
2016-06-08  7:49     ` Zheng, Lv
2016-06-08 20:17       ` Rafael J. Wysocki
2016-05-16  9:11 ` [PATCH 2/3] ACPI / sys: Update /sys/firmware/acpi/interrupts/gpexx using new GPE forced disabling/enabling mechanism Lv Zheng
2016-05-16  9:11   ` Lv Zheng
2016-05-16  9:11 ` Lv Zheng [this message]
2016-05-16  9:11   ` [PATCH 3/3] ACPI / sysfs: Provide quirk mechanism to prevent GPE flooding Lv Zheng
2016-06-23  6:20 ` [PATCH v2 0/3] ACPI / gpe: Add GPE masking/unmasking mechanism Lv Zheng
2016-06-23  6:20   ` Lv Zheng
2016-06-23  6:20   ` [PATCH v2 1/3] ACPICA: Events: Introduce acpi_mask_gpe()/acpi_unmask_gpe() to implement GPE masking mechanism Lv Zheng
2016-06-23  6:20     ` Lv Zheng
2016-07-04 13:59     ` [UPDATE PATCH v2 1/3] ACPICA: Events: Introduce acpi_mask_gpe() " Rafael J. Wysocki
2016-07-16  0:55       ` Rafael J. Wysocki
2016-07-18 10:34         ` Zheng, Lv
2016-06-23  6:20   ` [PATCH v2 2/3] ACPI / sys: Update /sys/firmware/acpi/interrupts/gpexx using new " Lv Zheng
2016-06-23  6:20     ` Lv Zheng
2016-06-23  6:20   ` [PATCH v2 3/3] ACPI / sysfs: Provide quirk mechanism to prevent GPE flooding Lv Zheng
2016-06-23  6:20     ` Lv Zheng
2016-07-04 14:07     ` Rafael J. Wysocki
2016-12-08  4:50 ` [PATCH v3] " Lv Zheng
2016-12-08  4:50   ` Lv Zheng
2016-12-16  4:07 ` [PATCH v4] " Lv Zheng

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=c6808078a092fbf990d535cc359b734108ae5d6b.1463389640.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: 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.