All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH 2/2] ACPI: detect GPE interrupt storm
@ 2008-06-20  1:42 Zhang Rui
  2008-06-20  5:26 ` Len Brown
  2008-06-20  6:55 ` Alexey Starikovskiy
  0 siblings, 2 replies; 4+ messages in thread
From: Zhang Rui @ 2008-06-20  1:42 UTC (permalink / raw)
  To: linux-acpi; +Cc: Len Brown, Zhang, Rui, Lin, Ming M, Alexey Starikovskiy

From: Ling Ming <ming.m.lin@intel.com>

Dectect GPE storm and disable a certain GPE if needed.

Introduce a new module parameter "debug_gpe_storm" as a runtime switch to
enable/disable this mechanism. The default value is TRUE, user can
"echo 0 > /sys/modules/acpi/parameters/debug_gpe_storm" to disable it.

Note: we try to disable a GPE if it's fired more than 1000 times in a second.
	And this 1000/s is just a wild guess currently. Need more tests to get a
	proper value.

Signed-off-by: Lin Ming <ming.m.lin@intel.com>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
---
 drivers/acpi/events/evgpe.c |   15 +++++++++++-
 drivers/acpi/system.c       |   55 ++++++++++++++++++++++++++++++++++++++++----
 include/acpi/acpiosxf.h     |    2 -
 3 files changed, 65 insertions(+), 7 deletions(-)

Index: linux-2.6/drivers/acpi/events/evgpe.c
===================================================================
--- linux-2.6.orig/drivers/acpi/events/evgpe.c	2008-06-20 09:27:00.000000000 +0800
+++ linux-2.6/drivers/acpi/events/evgpe.c	2008-06-20 09:34:32.000000000 +0800
@@ -623,7 +623,20 @@
 
 	ACPI_FUNCTION_TRACE(ev_gpe_dispatch);
 
-	acpi_os_gpe_count(gpe_number);
+	if (acpi_os_gpe_storm_detect(gpe_number)) {
+		/*
+		 * GPE storm detected, disable it automatically
+		 * To disable gpe storm detection:
+		 * "echo 0 > /sys/module/acpi/parameters/debug_gpe_storm"
+		 */
+		acpi_status status = acpi_ev_disable_gpe(gpe_event_info);
+		if (ACPI_FAILURE(status)) {
+			ACPI_EXCEPTION((AE_INFO, status,
+				"Unable to disable GPE[%2X]", gpe_number));
+		}
+
+		return_UINT32(ACPI_INTERRUPT_NOT_HANDLED);
+	}
 
 	/*
 	 * If edge-triggered, clear the GPE status bit now.  Note that
Index: linux-2.6/drivers/acpi/system.c
===================================================================
--- linux-2.6.orig/drivers/acpi/system.c	2008-06-20 09:27:00.000000000 +0800
+++ linux-2.6/drivers/acpi/system.c	2008-06-20 09:34:32.000000000 +0800
@@ -168,9 +168,14 @@
 #define NUM_COUNTERS_EXTRA 3
 
 #define ACPI_EVENT_VALID	0x01
+#define GPE_STORM_INTERVAL     HZ
+#define GPE_STORM_THRESHOLD    1000
+
 struct event_counter {
 	u32 count;
 	u32 flags;
+	u32 storm;
+	unsigned long last_time;
 };
 
 static struct event_counter *all_counters;
@@ -263,20 +268,60 @@
 	return;
 }
 
-void acpi_os_gpe_count(u32 gpe_number)
+/*
+ * acpi_gbl_gpe_lock is already acquired in acpi_ev_gpe_detect
+ */
+int check_gpe_storm(u32 gpe_number)
 {
+	struct event_counter *gpe_counter;
+
+	if (gpe_number >= num_gpes)
+		return 0;
+
+	gpe_counter = &all_counters[gpe_number];
+
+	if (time_after(jiffies, gpe_counter->last_time + GPE_STORM_INTERVAL)) {
+		gpe_counter->storm = 0;
+		gpe_counter->last_time = jiffies;
+	}
+
+	gpe_counter->storm++;
+	if (gpe_counter->storm > GPE_STORM_THRESHOLD) {
+		printk(KERN_WARNING "GPE[%2X] storm detected,"
+				"%d interrupts in %d milliseconds.\n",
+			gpe_number, gpe_counter->storm, GPE_STORM_INTERVAL);
+		gpe_counter->storm = 0;
+		gpe_counter->last_time = jiffies;
+
+		return 1;
+	}
+
+	return 0;
+}
+
+static int debug_gpe_storm = 1;
+module_param(debug_gpe_storm, bool, 0644);
+
+int acpi_os_gpe_storm_detect(u32 gpe_number)
+{
+	int storm = 0;
+
 	acpi_gpe_count++;
 
 	if (!all_counters)
-		return;
+		return storm;
 
-	if (gpe_number < num_gpes)
+	if (gpe_number < num_gpes) {
 		all_counters[gpe_number].count++;
+
+		/* If debug_gpe_storm enabled, check gpe storm */
+		if (debug_gpe_storm)
+			storm = check_gpe_storm(gpe_number);
+	}
 	else
 		all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_ERROR].
 					count++;
-
-	return;
+	return storm;
 }
 
 void acpi_os_fixed_event_count(u32 event_number)
Index: linux-2.6/include/acpi/acpiosxf.h
===================================================================
--- linux-2.6.orig/include/acpi/acpiosxf.h	2008-06-20 09:27:00.000000000 +0800
+++ linux-2.6/include/acpi/acpiosxf.h	2008-06-20 09:34:32.000000000 +0800
@@ -181,7 +181,7 @@
 acpi_status
 acpi_os_remove_interrupt_handler(u32 gsi, acpi_osd_handler service_routine);
 
-void acpi_os_gpe_count(u32 gpe_number);
+int acpi_os_gpe_storm_detect(u32 gpe_number);
 void acpi_os_fixed_event_count(u32 fixed_event_number);
 
 /*



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

* Re: [RFC PATCH 2/2] ACPI: detect GPE interrupt storm
  2008-06-20  1:42 [RFC PATCH 2/2] ACPI: detect GPE interrupt storm Zhang Rui
@ 2008-06-20  5:26 ` Len Brown
  2008-06-23  5:19   ` Lin Ming
  2008-06-20  6:55 ` Alexey Starikovskiy
  1 sibling, 1 reply; 4+ messages in thread
From: Len Brown @ 2008-06-20  5:26 UTC (permalink / raw)
  To: Zhang Rui; +Cc: linux-acpi, Lin, Ming M, Alexey Starikovskiy


A GPE storm is a bug.

I think the mechanism in the previous patch to deal with that
failure is sufficient.  I don't like embedding heuristic policy
into the kernel all for the benefit of broken systems.
We'll never know if the heuristic is correct, and there
is always the risk that we impact an otherwise working system.

User-space can detect a GPE storm via /proc/interrupts
and /sys/firmware/acpi/interrupts, and handle it that way.
(and then we can debug the root cause of the failure,
 rather than have it hidden by the kernel)

-Len


On Fri, 20 Jun 2008, Zhang Rui wrote:

> From: Ling Ming <ming.m.lin@intel.com>
> 
> Dectect GPE storm and disable a certain GPE if needed.
> 
> Introduce a new module parameter "debug_gpe_storm" as a runtime switch to
> enable/disable this mechanism. The default value is TRUE, user can
> "echo 0 > /sys/modules/acpi/parameters/debug_gpe_storm" to disable it.
> 
> Note: we try to disable a GPE if it's fired more than 1000 times in a second.
> 	And this 1000/s is just a wild guess currently. Need more tests to get a
> 	proper value.
> 
> Signed-off-by: Lin Ming <ming.m.lin@intel.com>
> Signed-off-by: Zhang Rui <rui.zhang@intel.com>
> ---
>  drivers/acpi/events/evgpe.c |   15 +++++++++++-
>  drivers/acpi/system.c       |   55 ++++++++++++++++++++++++++++++++++++++++----
>  include/acpi/acpiosxf.h     |    2 -
>  3 files changed, 65 insertions(+), 7 deletions(-)
> 
> Index: linux-2.6/drivers/acpi/events/evgpe.c
> ===================================================================
> --- linux-2.6.orig/drivers/acpi/events/evgpe.c	2008-06-20 09:27:00.000000000 +0800
> +++ linux-2.6/drivers/acpi/events/evgpe.c	2008-06-20 09:34:32.000000000 +0800
> @@ -623,7 +623,20 @@
>  
>  	ACPI_FUNCTION_TRACE(ev_gpe_dispatch);
>  
> -	acpi_os_gpe_count(gpe_number);
> +	if (acpi_os_gpe_storm_detect(gpe_number)) {
> +		/*
> +		 * GPE storm detected, disable it automatically
> +		 * To disable gpe storm detection:
> +		 * "echo 0 > /sys/module/acpi/parameters/debug_gpe_storm"
> +		 */
> +		acpi_status status = acpi_ev_disable_gpe(gpe_event_info);
> +		if (ACPI_FAILURE(status)) {
> +			ACPI_EXCEPTION((AE_INFO, status,
> +				"Unable to disable GPE[%2X]", gpe_number));
> +		}
> +
> +		return_UINT32(ACPI_INTERRUPT_NOT_HANDLED);
> +	}
>  
>  	/*
>  	 * If edge-triggered, clear the GPE status bit now.  Note that
> Index: linux-2.6/drivers/acpi/system.c
> ===================================================================
> --- linux-2.6.orig/drivers/acpi/system.c	2008-06-20 09:27:00.000000000 +0800
> +++ linux-2.6/drivers/acpi/system.c	2008-06-20 09:34:32.000000000 +0800
> @@ -168,9 +168,14 @@
>  #define NUM_COUNTERS_EXTRA 3
>  
>  #define ACPI_EVENT_VALID	0x01
> +#define GPE_STORM_INTERVAL     HZ
> +#define GPE_STORM_THRESHOLD    1000
> +
>  struct event_counter {
>  	u32 count;
>  	u32 flags;
> +	u32 storm;
> +	unsigned long last_time;
>  };
>  
>  static struct event_counter *all_counters;
> @@ -263,20 +268,60 @@
>  	return;
>  }
>  
> -void acpi_os_gpe_count(u32 gpe_number)
> +/*
> + * acpi_gbl_gpe_lock is already acquired in acpi_ev_gpe_detect
> + */
> +int check_gpe_storm(u32 gpe_number)
>  {
> +	struct event_counter *gpe_counter;
> +
> +	if (gpe_number >= num_gpes)
> +		return 0;
> +
> +	gpe_counter = &all_counters[gpe_number];
> +
> +	if (time_after(jiffies, gpe_counter->last_time + GPE_STORM_INTERVAL)) {
> +		gpe_counter->storm = 0;
> +		gpe_counter->last_time = jiffies;
> +	}
> +
> +	gpe_counter->storm++;
> +	if (gpe_counter->storm > GPE_STORM_THRESHOLD) {
> +		printk(KERN_WARNING "GPE[%2X] storm detected,"
> +				"%d interrupts in %d milliseconds.\n",
> +			gpe_number, gpe_counter->storm, GPE_STORM_INTERVAL);
> +		gpe_counter->storm = 0;
> +		gpe_counter->last_time = jiffies;
> +
> +		return 1;
> +	}
> +
> +	return 0;
> +}
> +
> +static int debug_gpe_storm = 1;
> +module_param(debug_gpe_storm, bool, 0644);
> +
> +int acpi_os_gpe_storm_detect(u32 gpe_number)
> +{
> +	int storm = 0;
> +
>  	acpi_gpe_count++;
>  
>  	if (!all_counters)
> -		return;
> +		return storm;
>  
> -	if (gpe_number < num_gpes)
> +	if (gpe_number < num_gpes) {
>  		all_counters[gpe_number].count++;
> +
> +		/* If debug_gpe_storm enabled, check gpe storm */
> +		if (debug_gpe_storm)
> +			storm = check_gpe_storm(gpe_number);
> +	}
>  	else
>  		all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_ERROR].
>  					count++;
> -
> -	return;
> +	return storm;
>  }
>  
>  void acpi_os_fixed_event_count(u32 event_number)
> Index: linux-2.6/include/acpi/acpiosxf.h
> ===================================================================
> --- linux-2.6.orig/include/acpi/acpiosxf.h	2008-06-20 09:27:00.000000000 +0800
> +++ linux-2.6/include/acpi/acpiosxf.h	2008-06-20 09:34:32.000000000 +0800
> @@ -181,7 +181,7 @@
>  acpi_status
>  acpi_os_remove_interrupt_handler(u32 gsi, acpi_osd_handler service_routine);
>  
> -void acpi_os_gpe_count(u32 gpe_number);
> +int acpi_os_gpe_storm_detect(u32 gpe_number);
>  void acpi_os_fixed_event_count(u32 fixed_event_number);
>  
>  /*
> 
> 

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

* Re: [RFC PATCH 2/2] ACPI: detect GPE interrupt storm
  2008-06-20  1:42 [RFC PATCH 2/2] ACPI: detect GPE interrupt storm Zhang Rui
  2008-06-20  5:26 ` Len Brown
@ 2008-06-20  6:55 ` Alexey Starikovskiy
  1 sibling, 0 replies; 4+ messages in thread
From: Alexey Starikovskiy @ 2008-06-20  6:55 UTC (permalink / raw)
  To: Zhang Rui; +Cc: linux-acpi, Len Brown, Lin, Ming M

NAK.
It is too low level to be useful, and if you will insist on lowering the threshold to something sane,
it will harm already broken situation, there driver does not know if it's working in interrupt or poll mode.

Regards,
Alex.

Zhang Rui wrote:
> From: Ling Ming <ming.m.lin@intel.com>
> 
> Dectect GPE storm and disable a certain GPE if needed.
> 
> Introduce a new module parameter "debug_gpe_storm" as a runtime switch to
> enable/disable this mechanism. The default value is TRUE, user can
> "echo 0 > /sys/modules/acpi/parameters/debug_gpe_storm" to disable it.
> 
> Note: we try to disable a GPE if it's fired more than 1000 times in a second.
> 	And this 1000/s is just a wild guess currently. Need more tests to get a
> 	proper value.
> 
> Signed-off-by: Lin Ming <ming.m.lin@intel.com>
> Signed-off-by: Zhang Rui <rui.zhang@intel.com>
> ---
>  drivers/acpi/events/evgpe.c |   15 +++++++++++-
>  drivers/acpi/system.c       |   55 ++++++++++++++++++++++++++++++++++++++++----
>  include/acpi/acpiosxf.h     |    2 -
>  3 files changed, 65 insertions(+), 7 deletions(-)
> 
> Index: linux-2.6/drivers/acpi/events/evgpe.c
> ===================================================================
> --- linux-2.6.orig/drivers/acpi/events/evgpe.c	2008-06-20 09:27:00.000000000 +0800
> +++ linux-2.6/drivers/acpi/events/evgpe.c	2008-06-20 09:34:32.000000000 +0800
> @@ -623,7 +623,20 @@
>  
>  	ACPI_FUNCTION_TRACE(ev_gpe_dispatch);
>  
> -	acpi_os_gpe_count(gpe_number);
> +	if (acpi_os_gpe_storm_detect(gpe_number)) {
> +		/*
> +		 * GPE storm detected, disable it automatically
> +		 * To disable gpe storm detection:
> +		 * "echo 0 > /sys/module/acpi/parameters/debug_gpe_storm"
> +		 */
> +		acpi_status status = acpi_ev_disable_gpe(gpe_event_info);
> +		if (ACPI_FAILURE(status)) {
> +			ACPI_EXCEPTION((AE_INFO, status,
> +				"Unable to disable GPE[%2X]", gpe_number));
> +		}
> +
> +		return_UINT32(ACPI_INTERRUPT_NOT_HANDLED);
> +	}
>  
>  	/*
>  	 * If edge-triggered, clear the GPE status bit now.  Note that
> Index: linux-2.6/drivers/acpi/system.c
> ===================================================================
> --- linux-2.6.orig/drivers/acpi/system.c	2008-06-20 09:27:00.000000000 +0800
> +++ linux-2.6/drivers/acpi/system.c	2008-06-20 09:34:32.000000000 +0800
> @@ -168,9 +168,14 @@
>  #define NUM_COUNTERS_EXTRA 3
>  
>  #define ACPI_EVENT_VALID	0x01
> +#define GPE_STORM_INTERVAL     HZ
> +#define GPE_STORM_THRESHOLD    1000
> +
>  struct event_counter {
>  	u32 count;
>  	u32 flags;
> +	u32 storm;
> +	unsigned long last_time;
>  };
>  
>  static struct event_counter *all_counters;
> @@ -263,20 +268,60 @@
>  	return;
>  }
>  
> -void acpi_os_gpe_count(u32 gpe_number)
> +/*
> + * acpi_gbl_gpe_lock is already acquired in acpi_ev_gpe_detect
> + */
> +int check_gpe_storm(u32 gpe_number)
>  {
> +	struct event_counter *gpe_counter;
> +
> +	if (gpe_number >= num_gpes)
> +		return 0;
> +
> +	gpe_counter = &all_counters[gpe_number];
> +
> +	if (time_after(jiffies, gpe_counter->last_time + GPE_STORM_INTERVAL)) {
> +		gpe_counter->storm = 0;
> +		gpe_counter->last_time = jiffies;
> +	}
> +
> +	gpe_counter->storm++;
> +	if (gpe_counter->storm > GPE_STORM_THRESHOLD) {
> +		printk(KERN_WARNING "GPE[%2X] storm detected,"
> +				"%d interrupts in %d milliseconds.\n",
> +			gpe_number, gpe_counter->storm, GPE_STORM_INTERVAL);
> +		gpe_counter->storm = 0;
> +		gpe_counter->last_time = jiffies;
> +
> +		return 1;
> +	}
> +
> +	return 0;
> +}
> +
> +static int debug_gpe_storm = 1;
> +module_param(debug_gpe_storm, bool, 0644);
> +
> +int acpi_os_gpe_storm_detect(u32 gpe_number)
> +{
> +	int storm = 0;
> +
>  	acpi_gpe_count++;
>  
>  	if (!all_counters)
> -		return;
> +		return storm;
>  
> -	if (gpe_number < num_gpes)
> +	if (gpe_number < num_gpes) {
>  		all_counters[gpe_number].count++;
> +
> +		/* If debug_gpe_storm enabled, check gpe storm */
> +		if (debug_gpe_storm)
> +			storm = check_gpe_storm(gpe_number);
> +	}
>  	else
>  		all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_ERROR].
>  					count++;
> -
> -	return;
> +	return storm;
>  }
>  
>  void acpi_os_fixed_event_count(u32 event_number)
> Index: linux-2.6/include/acpi/acpiosxf.h
> ===================================================================
> --- linux-2.6.orig/include/acpi/acpiosxf.h	2008-06-20 09:27:00.000000000 +0800
> +++ linux-2.6/include/acpi/acpiosxf.h	2008-06-20 09:34:32.000000000 +0800
> @@ -181,7 +181,7 @@
>  acpi_status
>  acpi_os_remove_interrupt_handler(u32 gsi, acpi_osd_handler service_routine);
>  
> -void acpi_os_gpe_count(u32 gpe_number);
> +int acpi_os_gpe_storm_detect(u32 gpe_number);
>  void acpi_os_fixed_event_count(u32 fixed_event_number);
>  
>  /*
> 
> 


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

* Re: [RFC PATCH 2/2] ACPI: detect GPE interrupt storm
  2008-06-20  5:26 ` Len Brown
@ 2008-06-23  5:19   ` Lin Ming
  0 siblings, 0 replies; 4+ messages in thread
From: Lin Ming @ 2008-06-23  5:19 UTC (permalink / raw)
  To: Len Brown; +Cc: Zhang Rui, linux-acpi, Alexey Starikovskiy


On Fri, 2008-06-20 at 01:26 -0400, Len Brown wrote:
> A GPE storm is a bug.
> 
> I think the mechanism in the previous patch to deal with that
> failure is sufficient.  I don't like embedding heuristic policy
> into the kernel all for the benefit of broken systems.
> We'll never know if the heuristic is correct, and there
> is always the risk that we impact an otherwise working system.
> 
> User-space can detect a GPE storm via /proc/interrupts
> and /sys/firmware/acpi/interrupts, and handle it that way.
> (and then we can debug the root cause of the failure,
>  rather than have it hidden by the kernel)

Agree. Just keep this as a "debug patch".

Lin Ming

> 
> -Len
> 
> 
> On Fri, 20 Jun 2008, Zhang Rui wrote:
> 
> > From: Ling Ming <ming.m.lin@intel.com>
> > 
> > Dectect GPE storm and disable a certain GPE if needed.
> > 
> > Introduce a new module parameter "debug_gpe_storm" as a runtime switch to
> > enable/disable this mechanism. The default value is TRUE, user can
> > "echo 0 > /sys/modules/acpi/parameters/debug_gpe_storm" to disable it.
> > 
> > Note: we try to disable a GPE if it's fired more than 1000 times in a second.
> > 	And this 1000/s is just a wild guess currently. Need more tests to get a
> > 	proper value.
> > 
> > Signed-off-by: Lin Ming <ming.m.lin@intel.com>
> > Signed-off-by: Zhang Rui <rui.zhang@intel.com>
> > ---
> >  drivers/acpi/events/evgpe.c |   15 +++++++++++-
> >  drivers/acpi/system.c       |   55 ++++++++++++++++++++++++++++++++++++++++----
> >  include/acpi/acpiosxf.h     |    2 -
> >  3 files changed, 65 insertions(+), 7 deletions(-)
> > 
> > Index: linux-2.6/drivers/acpi/events/evgpe.c
> > ===================================================================
> > --- linux-2.6.orig/drivers/acpi/events/evgpe.c	2008-06-20 09:27:00.000000000 +0800
> > +++ linux-2.6/drivers/acpi/events/evgpe.c	2008-06-20 09:34:32.000000000 +0800
> > @@ -623,7 +623,20 @@
> >  
> >  	ACPI_FUNCTION_TRACE(ev_gpe_dispatch);
> >  
> > -	acpi_os_gpe_count(gpe_number);
> > +	if (acpi_os_gpe_storm_detect(gpe_number)) {
> > +		/*
> > +		 * GPE storm detected, disable it automatically
> > +		 * To disable gpe storm detection:
> > +		 * "echo 0 > /sys/module/acpi/parameters/debug_gpe_storm"
> > +		 */
> > +		acpi_status status = acpi_ev_disable_gpe(gpe_event_info);
> > +		if (ACPI_FAILURE(status)) {
> > +			ACPI_EXCEPTION((AE_INFO, status,
> > +				"Unable to disable GPE[%2X]", gpe_number));
> > +		}
> > +
> > +		return_UINT32(ACPI_INTERRUPT_NOT_HANDLED);
> > +	}
> >  
> >  	/*
> >  	 * If edge-triggered, clear the GPE status bit now.  Note that
> > Index: linux-2.6/drivers/acpi/system.c
> > ===================================================================
> > --- linux-2.6.orig/drivers/acpi/system.c	2008-06-20 09:27:00.000000000 +0800
> > +++ linux-2.6/drivers/acpi/system.c	2008-06-20 09:34:32.000000000 +0800
> > @@ -168,9 +168,14 @@
> >  #define NUM_COUNTERS_EXTRA 3
> >  
> >  #define ACPI_EVENT_VALID	0x01
> > +#define GPE_STORM_INTERVAL     HZ
> > +#define GPE_STORM_THRESHOLD    1000
> > +
> >  struct event_counter {
> >  	u32 count;
> >  	u32 flags;
> > +	u32 storm;
> > +	unsigned long last_time;
> >  };
> >  
> >  static struct event_counter *all_counters;
> > @@ -263,20 +268,60 @@
> >  	return;
> >  }
> >  
> > -void acpi_os_gpe_count(u32 gpe_number)
> > +/*
> > + * acpi_gbl_gpe_lock is already acquired in acpi_ev_gpe_detect
> > + */
> > +int check_gpe_storm(u32 gpe_number)
> >  {
> > +	struct event_counter *gpe_counter;
> > +
> > +	if (gpe_number >= num_gpes)
> > +		return 0;
> > +
> > +	gpe_counter = &all_counters[gpe_number];
> > +
> > +	if (time_after(jiffies, gpe_counter->last_time + GPE_STORM_INTERVAL)) {
> > +		gpe_counter->storm = 0;
> > +		gpe_counter->last_time = jiffies;
> > +	}
> > +
> > +	gpe_counter->storm++;
> > +	if (gpe_counter->storm > GPE_STORM_THRESHOLD) {
> > +		printk(KERN_WARNING "GPE[%2X] storm detected,"
> > +				"%d interrupts in %d milliseconds.\n",
> > +			gpe_number, gpe_counter->storm, GPE_STORM_INTERVAL);
> > +		gpe_counter->storm = 0;
> > +		gpe_counter->last_time = jiffies;
> > +
> > +		return 1;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static int debug_gpe_storm = 1;
> > +module_param(debug_gpe_storm, bool, 0644);
> > +
> > +int acpi_os_gpe_storm_detect(u32 gpe_number)
> > +{
> > +	int storm = 0;
> > +
> >  	acpi_gpe_count++;
> >  
> >  	if (!all_counters)
> > -		return;
> > +		return storm;
> >  
> > -	if (gpe_number < num_gpes)
> > +	if (gpe_number < num_gpes) {
> >  		all_counters[gpe_number].count++;
> > +
> > +		/* If debug_gpe_storm enabled, check gpe storm */
> > +		if (debug_gpe_storm)
> > +			storm = check_gpe_storm(gpe_number);
> > +	}
> >  	else
> >  		all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_ERROR].
> >  					count++;
> > -
> > -	return;
> > +	return storm;
> >  }
> >  
> >  void acpi_os_fixed_event_count(u32 event_number)
> > Index: linux-2.6/include/acpi/acpiosxf.h
> > ===================================================================
> > --- linux-2.6.orig/include/acpi/acpiosxf.h	2008-06-20 09:27:00.000000000 +0800
> > +++ linux-2.6/include/acpi/acpiosxf.h	2008-06-20 09:34:32.000000000 +0800
> > @@ -181,7 +181,7 @@
> >  acpi_status
> >  acpi_os_remove_interrupt_handler(u32 gsi, acpi_osd_handler service_routine);
> >  
> > -void acpi_os_gpe_count(u32 gpe_number);
> > +int acpi_os_gpe_storm_detect(u32 gpe_number);
> >  void acpi_os_fixed_event_count(u32 fixed_event_number);
> >  
> >  /*
> > 
> > 


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

end of thread, other threads:[~2008-06-23  5:20 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-06-20  1:42 [RFC PATCH 2/2] ACPI: detect GPE interrupt storm Zhang Rui
2008-06-20  5:26 ` Len Brown
2008-06-23  5:19   ` Lin Ming
2008-06-20  6:55 ` Alexey Starikovskiy

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.