Skip to contentSkip to conversation

ACPI interrupt statistics

RFC In review Len Brown 2 participants 3 messages Nov 3, 2007 – Nov 24, 2007

Subsystems (2)
lore
Share & tools
lore

Len Brown

author reviewer
#0 lore raw

RFC 1/1 ACPI interrupt statistics

For your review and testing...

The patch below exports interrupt counters from within ACPI so that developers can better understand the cause of ACPI interrupts.

My intent is to have something like this built in by default starting in 2.6.25. The version below applies to 2.6.21 and is originally based on a patch by Luming Yu.

I'll probably move most of the code to system.c from osl.c, and I'll port it to 2.6.24;
but otherwise, it seems to be doing what I wanted it to do...

One idea is that a user-space application could select() an individual GPE file in order to notice
when a particular GPE fires. This might be useful
for user-space platform specific code -- say allowing it to recognize a GPE without requiring any platform-specific kernel code...

$ cd /sys/firmware/acpi/interrupts/
$ ls
gpe0   gpe11  gpe14  gpe17  gpe2   gpe22  gpe25  gpe28  gpe30  gpe5  gpe8
gpe1   gpe12  gpe15  gpe18  gpe20  gpe23  gpe26  gpe29  gpe31  gpe6  gpe9
gpe10  gpe13  gpe16  gpe19  gpe21  gpe24  gpe27  gpe3   gpe4   gpe7  summary
$ cat summary
pm_timer     0
glbl_lock    0
power_btn    0
sleep_btn    0
rtc          0
gpe0      0
gpe1      0
gpe2      0
gpe3      0
gpe4      0
gpe5      0
gpe6      0
gpe7      0
gpe8      0
gpe9      2
gpe10     0
gpe11     0
gpe12     0
gpe13     0
gpe14     0
gpe15     0
gpe16     0
gpe17    60
gpe18     0
gpe19     0
gpe20     0
gpe21     0
gpe22     0
gpe23     0
gpe24     0
gpe25     0
gpe26     0
gpe27     0
gpe28     0
gpe29     0
gpe30     0
gpe31     0
gpe_hi    0
gpe_total   62
acpi_irq    62
$ cat gpe17
60
# echo 0 > summary
# cat summary
(all zeros)
---
 drivers/acpi/bus.c                |   44 +++
 drivers/acpi/events/evevent.c     |    2
 drivers/acpi/events/evgpe.c       |    2
 drivers/acpi/osl.c                |  232 +++++++++++++++++-
 drivers/acpi/utilities/utglobal.c |    2
 include/acpi/acglobal.h           |    1
 include/acpi/aclocal.h            |    1
 include/acpi/acpiosxf.h           |    3
 include/linux/acpi.h              |    6
 9 files changed, 290 insertions(+), 3 deletions(-)
drivers/acpi/bus.c +43 -1
index dd49ea0..b1a8b24 100644
@@ -735,6 +735,47 @@ static int __init acpi_bus_init(void)
 
 decl_subsys(acpi, NULL, NULL);
 
+struct acpi_subsys_attr {
+	struct attribute attr;
+	int type;
+	int value;
+	ssize_t(*show) (struct attribute *, char *);
+	ssize_t(*store) (struct attribute *, const char *, size_t count);
+};
+#define to_acpi_attr(k) container_of(k,struct acpi_subsys_attr,attr)
+static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf)
+{
+	struct acpi_subsys_attr *aattr = to_acpi_attr(attr);
+	if (aattr->show)
+		return aattr->show(attr, buf);
+	else
+		return -EIO;
+}
+
+static ssize_t store(struct kobject *kobj, struct attribute *attr,
+			const char *buf, size_t count)
+{
+	struct acpi_subsys_attr *aattr = to_acpi_attr(attr);
+	if (aattr->store)
+		return aattr->store(attr, buf, count);
+	else
+		return -EIO;
+}
+static struct sysfs_ops sysfs_ops = {
+	.show = show,
+	.store = store,
+};
+
+static struct kobj_type ktype_acpi = {
+	.sysfs_ops = &sysfs_ops,
+};
+
+void acpi_subsys_set_sysfs_ops(void)
+{
+	acpi_subsys.kset.kobj.ktype = &ktype_acpi;
+	acpi_subsys.kset.ktype = &ktype_acpi;
+}
+
 static int __init acpi_init(void)
 {
 	int result = 0;
@@ -749,7 +790,7 @@ static int __init acpi_init(void)
 	if (result < 0
 		printk(KERN_WARNING "%s: firmware_register error: %d\n",
 			__FUNCTION__, result);
-
+	acpi_subsys_set_sysfs_ops();
 	result = acpi_bus_init();
 
 	if (!result) {
@@ -769,4 +810,5 @@ static int __init acpi_init(void)
 	return result;
 }
 
+EXPORT_SYMBOL(acpi_subsys);
 subsys_initcall(acpi_init);
drivers/acpi/events/evevent.c +1 -1
index a1f87b5..8bf4dbe 100644
@@ -261,7 +261,7 @@ u32 acpi_ev_fixed_event_detect(void)
 			enable_bit_mask)) {
 
 			/* Found an active (signalled) event */
-
+			acpi_fixed_event_count[i]++;
 			int_status |= acpi_ev_fixed_event_dispatch((u32) i);
 		}
 	}
drivers/acpi/events/evgpe.c +2 -0
index 635ba44..76a91f4 100644
@@ -621,6 +621,8 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number)
 
 	acpi_gpe_count++;
 
+	acpi_os_gpe_count(gpe_number);
+
 	/*
 	 * If edge-triggered, clear the GPE status bit now.  Note that
 	 * level-triggered events are cleared after the GPE is serviced.
drivers/acpi/osl.c +231 -1

259 lines not on this page · raw message

drivers/acpi/utilities/utglobal.c +2 -0
index af33358..fbb9bec 100644
@@ -673,6 +673,8 @@ void acpi_ut_init_globals(void)
 	/* GPE support */
 
 	acpi_gpe_count = 0;
+	for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++)
+		acpi_fixed_event_count[i] = 0;
 	acpi_gbl_gpe_xrupt_list_head = NULL;
 	acpi_gbl_gpe_fadt_blocks[0] = NULL;
 	acpi_gbl_gpe_fadt_blocks[1] = NULL;
include/acpi/acglobal.h +1 -0
index 24c3f05..a27ba06 100644
@@ -120,6 +120,7 @@ extern u32 acpi_gbl_nesting_level;
 /* Event counters */
 
 ACPI_EXTERN u32 acpi_gpe_count;
+ACPI_EXTERN u32 acpi_fixed_event_count[ACPI_NUM_FIXED_EVENTS];
 
 /* Support for dynamic control method tracing mechanism */
 
include/acpi/aclocal.h +1 -0
index 6f83ddb..380a8a8 100644
@@ -368,6 +368,7 @@ struct acpi_gpe_event_info {
 	struct acpi_gpe_register_info *register_info;	/* Backpointer to register info */
 	u8 flags;		/* Misc info about this GPE */
 	u8 gpe_number;		/* This GPE */
+	u32 count;
 };
 
 /* Information about a GPE register pair, one per each status/enable pair in an array */
include/acpi/acpiosxf.h +3 -0
index 2785058..0d82437 100644
@@ -180,6 +180,9 @@ acpi_os_install_interrupt_handler(u32 gsi,
 acpi_status
 acpi_os_remove_interrupt_handler(u32 gsi, acpi_osd_handler service_routine);
 
+void
+acpi_os_gpe_count (u32 gpe_number);
+
 /*
  * Threads and Scheduling
  */
include/linux/acpi.h +6 -0
index 8bcfaa4..5bc7c84 100644
@@ -158,6 +158,12 @@ struct acpi_prt_list {
 	struct list_head	entries;
 };
 
+struct gpe_attr {
+	struct attribute attr;
+	int value;
+	ssize_t(*show) (struct attribute *, char *);
+	ssize_t(*store) (struct attribute *, const char *, size_t count);
+};
 struct pci_dev;
 
 int acpi_pci_irq_enable (struct pci_dev *dev);
#1 lore raw
Quoted 8 lines · On Saturday 03 November 2007 04:40:53 Len Brown wrote:

For your review and testing...

The patch below exports interrupt counters from within ACPI so that developers can better understand the cause of ACPI interrupts.

My intent is to have something like this built in by default starting in 2.6.25. The version below applies to 2.6.21 and is originally based on a patch by Luming Yu.

There have been a fair few changes since then, and this patch will probably need a fair bit of work.

1) Back in 2.6.21, acpi_subsys was defined as a 'struct subsystem' in acpi_bus.h - it's now a 'struct kset'

2) Greg KH has an RFC patch lined up that does even more work in this area -
http://lkml.org/lkml/2007/11/2

3) From my limited understanding of the area and intent, this patch seems to be a combination of kset work + the interrupt support - could it be split into two functionally separate patches to cover these instead?

(Basically, the only bit I'm really interested in is the EXPORT_SYMBOL(acpi_subsys), as acpi_subsys can currently only be used from built-in drivers, which is preventing me from converting wmi.c to a module).

-Carlos

Signature · 3 lines
E-Mail: [email protected]
Web: strangeworlds.co.uk
GPG Key ID: 0x23EE722D
author reviewer
#2 lore raw
Quoted 10 lines · Carlos Corbacho
Quoted 8 lines · On Saturday 03 November 2007 04:40:53 Len Brown wrote:

For your review and testing...

The patch below exports interrupt counters from within ACPI so that developers can better understand the cause of ACPI interrupts.

My intent is to have something like this built in by default starting in 2.6.25. The version below applies to 2.6.21 and is originally based on a patch by Luming Yu.

Quoted 5 lines

There have been a fair few changes since then, and this patch will probably need a fair bit of work.

1) Back in 2.6.21, acpi_subsys was defined as a 'struct subsystem' in acpi_bus.h - it's now a 'struct kset'

yep, that is what broke it.

Quoted 2 lines

2) Greg KH has an RFC patch lined up that does even more work in this area -
http://lkml.org/lkml/2007/11/2

yeah, i noticed that too -- we already ran amuck of them with some other patches in the acpi tree... akpm patched it up in mm.

Quoted 3 lines

3) From my limited understanding of the area and intent, this patch seems to be a combination of kset work + the interrupt support - could it be split into two functionally separate patches to cover these instead?

the patch I sent to the list is actually a roll-up of a patch series, so more patches will appear in the tree when it hits 2.6.25.

Quoted 3 lines

(Basically, the only bit I'm really interested in is the EXPORT_SYMBOL(acpi_subsys), as acpi_subsys can currently only be used from built-in drivers, which is preventing me from converting wmi.c to a module).

hmm, okay, i didn't know that.
but feel free to pre-pend a non-wmi patch to your wmi series if you need it.

thanks,
-Len