ACPI: Create /sys/firmware/acpi/interrupts/ counters
Subsystems (2)
Len Brown
reviewerPATCH 1/1 ACPI: Create /sys/firmware/acpi/interrupts/ counters
From: Len Brown <[email protected]>
Here is the ACPI GPE statistics patch, forward ported to grok 2.6.25's kobject changes. (Greg, let me know if I was able to unleash the inner beauty of the kobj interface) (yes, I know you don't like sysfs files with more than 1 value,
but I violate that rule for only one of the 33 files:-)
thanks,
-Len
--
# ls /sys/firmware/acpi/interrupts/ gpe00 gpe02 gpe04 gpe06 gpe08 gpe0A gpe0C gpe0E gpe10 gpe12 gpe14 gpe16 gpe18 gpe1A gpe1C gpe1E summary gpe01 gpe03 gpe05 gpe07 gpe09 gpe0B gpe0D gpe0F gpe11 gpe13 gpe15 gpe17 gpe19 gpe1B gpe1D gpe1F
# cat /sys/firmware/acpi/interrupts/summary pm_timer 0 glbl_lock 0 power_btn 0 sleep_btn 0 rtc 0 gpe00 0 gpe01 0 gpe02 0 gpe03 0 gpe04 0 gpe05 0 gpe06 0 gpe07 0 gpe08 0 gpe09 2 gpe0A 0 gpe0B 0 gpe0C 0 gpe0D 0 gpe0E 0 gpe0F 0 gpe10 0 gpe11 60 gpe12 0 gpe13 0 gpe14 0 gpe15 0 gpe16 0 gpe17 0 gpe18 0 gpe19 1 gpe1A 0 gpe1B 0 gpe1C 0 gpe1D 0 gpe1E 0 gpe1F 0 gpe_hi 0 gpe_total 63 acpi_irq 63
--- drivers/acpi/events/evevent.c | 2 +- drivers/acpi/events/evgpe.c | 2 + drivers/acpi/osl.c | 12 ++- drivers/acpi/system.c | 218 +++++++++++++++++++++++++++++++++++++ drivers/acpi/utilities/utglobal.c | 2 + include/acpi/acglobal.h | 1 + include/acpi/aclocal.h | 1 + include/acpi/acpiosxf.h | 2 + include/linux/acpi.h | 2 + 9 files changed, 240 insertions(+), 2 deletions(-)
drivers/acpi/events/evevent.c +1 -1
@@ -259,7 +259,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
@@ -620,6 +620,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 +11 -1
@@ -332,7 +332,15 @@ acpi_os_table_override(struct acpi_table_header * existing_table,static irqreturn_t acpi_irq (int irq,void *dev_id) { -return (*acpi_irq_handler) (acpi_irq_context) ?IRQ_HANDLED :IRQ_NONE ; +u32 handled; + + handled = (*acpi_irq_handler) (acpi_irq_context); + +if (handled) { + acpi_irq_handled++; +return IRQ_HANDLED ; + }else +return IRQ_NONE ; } acpi_status
@@ -341,6 +349,8 @@ acpi_os_install_interrupt_handler(u32 gsi, acpi_osd_handler handler, {unsigned int irq; +acpi_irq_stats_init (); +/* * Ignore the GSI from the core, and use the value in our copy of the * FADT. It may not be the same if an interrupt source override exists
drivers/acpi/system.c +218 -0
230 lines not on this page · raw message
drivers/acpi/utilities/utglobal.c +2 -0
@@ -672,6 +672,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
@@ -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
@@ -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 +2 -0
@@ -181,6 +181,8 @@ 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 +2 -0
@@ -115,7 +115,9 @@ int acpi_unmap_lsapic(int cpu);int acpi_register_ioapic (acpi_handle handle,u64 phys_addr,u32 gsi_base);int acpi_unregister_ioapic (acpi_handle handle,u32 gsi_base); +void acpi_irq_stats_init (void ); +extern u32 acpi_irq_handled;extern int acpi_mp_config;extern struct acpi_mcfg_allocation *pci_mmcfg_config;
Signature · 1 line
1.5.4.18.gd0b8
Quoted 33 lines · Len Brown
# cat /sys/firmware/acpi/interrupts/summary pm_timer 0 glbl_lock 0 power_btn 0 sleep_btn 0 rtc 0 gpe00 0 gpe01 0 gpe02 0 gpe03 0 gpe04 0 gpe05 0 gpe06 0 gpe07 0 gpe08 0 gpe09 2 gpe0A 0 gpe0B 0 gpe0C 0 gpe0D 0 gpe0E 0 gpe0F 0 gpe10 0 gpe11 60 gpe12 0 gpe13 0 gpe14 0 gpe15 0 gpe16 0 gpe17 0 gpe18 0 gpe19 1 gpe1A 0
Quoted 8 lines
gpe1B 0 gpe1C 0 gpe1D 0 gpe1E 0 gpe1F 0 gpe_hi 0 gpe_total 63 acpi_irq 63
Eeek! Why? What's wrong with individual files here? What's to ensure that you aren't going to overflow your buffer? There's a reason we don't have the seq file interface for sysfs, to prevent this very kind of thing...
drivers/acpi/system.c static int acpi_system_sysfs_init(void) · line 264
Quoted 7 lines
drivers/acpi/system.c +7
-0+/* +* General Purpose Events +*/ +for (i =0 ; i < number_of_gpes; i++) { + count +=sprintf (buf + count,"gpe%02X %4d\n" , + i, acpi_gpe_counters[i]); + }
Nope, no error checking, fun chance of blowing the memory buffer :(
Please change the interface to not do this.
Oh, and for every new sysfs file, you need a Documentation/ABI/ addition, please also add that.
thanks,
greg k-h
Len Brown
reviewerQuoted 8 lines · Greg KH
Quoted 7 lines · Len Brown
# cat /sys/firmware/acpi/interrupts/summary pm_timer 0 glbl_lock 0 power_btn 0 sleep_btn 0 rtc 0 gpe00 0
...
Quoted 6 lines
Quoted 4 lines
gpe1F 0
gpe_hi0gpe_total63acpi_irq63Eeek! Why? What's wrong with individual files here?
My expectation is that this is a shell interface for debugging, not an API for programs. ala /proc/interrupts.
if we have 40 individual files, each with a number in it, it is less convenient to cat the file and paste the results into an email or bug report and have the receiver easily see what what count goes with what file -- or is there a version of cat that prints the file name before the contents of each file?
I've seen
more * | cat
but one has to wonder why an interface would be built to make something so simple not be simple.
Quoted 2 lines
What's to ensure
that you aren't going to overflow your buffer?
Good question. What's to ensure we don't overflow it when I print any other random string?
Who allocates it and how big is it?
Quoted 3 lines
There's a reason we
don't have the seq file interface for sysfs, to prevent this very kind of thing...
If sysfs can't handle it, I suppose I could instead print the needed information to the console....
Quoted 9 lines
drivers/acpi/system.c static int acpi_system_sysfs_init(void) · line 264
Quoted 7 lines
drivers/acpi/system.c +7
-0+/* +* General Purpose Events +*/ +for (i =0 ; i < number_of_gpes; i++) { + count +=sprintf (buf + count,"gpe%02X %4d\n" , + i, acpi_gpe_counters[i]); + }Nope, no error checking, fun chance of blowing the memory buffer :(
you're right, there is rumour of a future machine with more than 32 GPEs...
Quoted 4 lines
Please change the interface to not do this.
Oh, and for every new sysfs file, you need a
Documentation/ABI/addition, please also add that.
ok.
thanks,
-Len
Quoted 15 lines · Len Brown
Quoted 8 lines · Greg KH
Quoted 7 lines · Len Brown
# cat /sys/firmware/acpi/interrupts/summary pm_timer 0 glbl_lock 0 power_btn 0 sleep_btn 0 rtc 0 gpe00 0...
Quoted 5 lines
Quoted 4 lines
gpe1F 0
gpe_hi0gpe_total63acpi_irq63
Quoted 4 lines
Quoted 1 line
Eeek! Why? What's wrong with individual files here?
My expectation is that this is a shell interface for debugging, not an API for programs. ala
/proc/interrupts.
Great, then use debugfs for it. Please, don't put debug stuff like this in sysfs, that's not what it is there for. You can do whatever you want in debugfs :)
Quoted 11 lines
if we have 40 individual files, each with a number in it, it is less convenient to cat the file and paste the results into an email or bug report and have the receiver easily see what what count goes with what file -- or is there a version of cat that prints the file name before the contents of each file?
I've seen
more * | cat
but one has to wonder why an interface would be built to make something so simple not be simple.
Use debugfs please.
Quoted 6 lines
Quoted 2 lines
What's to ensure
that you aren't going to overflow your buffer?Good question. What's to ensure we don't overflow it when I print any other random string?
Who allocates it and how big is it?
The core does, and if you are putting something too big in it, you are using the sysfs interface wrong :)
Simple, one value per file is what sysfs is for. Use debugfs for debugging stuff.
thanks,
greg k-h
Quoted 3 lines · Len Brown
is there
a version of cat that prints the file name before
the contents of each file?
I use "grep . *" for this sort of thing.
Len Brown
reviewerQuoted 6 lines · Bjorn Helgaas
Quoted 3 lines · Len Brown
is there
a version of cat that prints the file name before
the contents of each file?I use "grep . *" for this sort of thing.
good tip, bjorn, thanks!
/sys/devices/system/cpu/cpu0/cpufreq # grep . *
affected_cpus:0
cpuinfo_cur_freq:1596000
cpuinfo_max_freq:2660000
cpuinfo_min_freq:1596000
scaling_available_frequencies:2660000 2128000 1596000 scaling_available_governors:conservative ondemand userspace powersave performance scaling_cur_freq:1596000
scaling_driver:centrino
scaling_governor:ondemand
scaling_max_freq:2660000
scaling_min_freq:1596000
Len Brown
reviewerQuoted 16 lines · Greg KH
Quoted 15 lines · Len Brown
Quoted 8 lines · Greg KH
Quoted 7 lines · Len Brown
# cat /sys/firmware/acpi/interrupts/summary pm_timer 0 glbl_lock 0 power_btn 0 sleep_btn 0 rtc 0 gpe00 0...
Quoted 5 lines
Quoted 4 lines
gpe1F 0
gpe_hi0gpe_total63acpi_irq63
Quoted 8 lines
Quoted 4 lines
Quoted 1 line
Eeek! Why? What's wrong with individual files here?
My expectation is that this is a shell interface for debugging, not an API for programs. ala
/proc/interrupts.Great, then use debugfs for it. Please, don't put debug stuff like this in sysfs, that's not what it is there for. You can do whatever you want in debugfs :)
Can you point to a model of good behaviour that I can copy?
note that I want this information to be available on every system, just like /proc/interrupts is.
/proc/ has seqfile support, is there a reason I shouldn't use it? I'd banned additional files from /proc/acpi for a long time since the directory layout was ill-conceived. But maybe I should re-consider the headlong rush to use sysfs?
thanks,
-Len
Quoted 19 lines · Len Brown
Quoted 18 lines · Greg KH
Quoted 17 lines · Len Brown
Quoted 8 lines · Greg KH
Quoted 7 lines · Len Brown
# cat /sys/firmware/acpi/interrupts/summary pm_timer 0 glbl_lock 0 power_btn 0 sleep_btn 0 rtc 0 gpe00 0...
Quoted 6 lines
Quoted 4 lines
gpe1F 0
gpe_hi0gpe_total63acpi_irq63Eeek! Why? What's wrong with individual files here?
Quoted 8 lines
Quoted 6 lines
Quoted 2 lines
My expectation is that this is a shell interface for debugging, not an API for programs. ala
/proc/interrupts.Great, then use debugfs for it. Please, don't put debug stuff like this in sysfs, that's not what it is there for. You can do whatever you want in debugfs :)
Can you point to a model of good behaviour that I can copy?
Any user of the debugfs api you could copy for this.
Quoted 2 lines
note that I want this information to be available on every system, just like
/proc/interruptsis.
Ah, then /proc perhaps?
Quoted 4 lines
/proc/has seqfile support, is there a reason I shouldn't use it? I'd banned additional files from/proc/acpifor a long time since the directory layout was ill-conceived. But maybe I should re-consider the headlong rush to use sysfs?
One of the main problems of /proc was that the files were not documented, or that the format would change between versions, or that they were different on different arches.
For something like this, yes, maybe you do need to use proc. It can handle almost infinite length files, and just make sure you document it well.
But I would just stick with debugfs, all distros enable it when shipping, you just have to ask them to mount it by hand usually:
mount -t debugfs none /sys/kernel/debug/
Either way, I wouldn't recommend sysfs for this.
thanks,
greg k-h
Len Brown
reviewerThanks for the reply, Greg.
If these counters are not always available by default, then I've lost most of their value for supporting systems in the field.
Plus, I think I can live with just the individual sysfs files, given Bjorn's "grep . *" tip.
So if I follow the rules, do you think it is okay to put these stats in sysfs? In the hopes the answer is "yes", I'll reply with a refreshed patch
cheers,
-Len
Len Brown
reviewerPATCH 1/1 ACPI: create /sys/firmware/acpi/interrupts/ (v2)
From: Len Brown <[email protected]>
See Documentation/ABI/testing/sysfs-firmware-acpi
--- Documentation/ABI/testing/sysfs-firmware-acpi | 99 ++++++++++++ drivers/acpi/events/evevent.c | 2 +- drivers/acpi/events/evgpe.c | 2 +- drivers/acpi/osl.c | 12 ++- drivers/acpi/system.c | 208 +++++++++++++++++++++++++ drivers/acpi/utilities/utglobal.c | 2 - include/acpi/acglobal.h | 4 - include/acpi/acpiosxf.h | 3 + include/linux/acpi.h | 2 + 9 files changed, 325 insertions(+), 9 deletions(-) create mode 100644 Documentation/ABI/testing/sysfs-firmware-acpi
Documentation/ABI/testing/sysfs-firmware-acpi new file +99 -0
@@ -0,0 +1,99 @@ +What: /sys/firmware/acpi/interrupts/ +Date: February 2008 +Contact: Len Brown <[email protected]> +Description: + All ACPI interrupts are handled via a single IRQ, + the System Control Interrupt (SCI), which appears + as "acpi" in /proc/interrupts. + + However, one of the main functions of ACPI is to make + the platform understand random hardware without + special driver support. So while the SCI handles a few + well known (fixed feature) interrupts sources, such + as the power button, it can also handle a variable + number of a "General Purpose Events" (GPE). + + A GPE vectors to a specified handler in AML, which + can do a anything the BIOS writer wants from + OS context. GPE 0x12, for example, would vector + to a level or edge handler called _L12 or _E12. + The handler may do its business and return. + Or the handler may send send a Notify event + to a Linux device driver registered on an ACPI device, + such as a battery, or a processor. + + To figure out where all the SCI's are coming from, + /sys/firmware/acpi/interrupts contains a file listing + every possible source, and the count of how many + times it has triggered. + + $ cd /sys/firmware/acpi/interrupts + $ grep . * + error:0 + ff_gbl_lock:0 + ff_pmtimer:0 + ff_pwr_btn:0 + ff_rt_clk:0 + ff_slp_btn:0 + gpe00:0 + gpe01:0 + gpe02:0 + gpe03:0 + gpe04:0 + gpe05:0 + gpe06:0 + gpe07:0 + gpe08:0 + gpe09:174 + gpe0A:0 + gpe0B:0 + gpe0C:0 + gpe0D:0 + gpe0E:0 + gpe0F:0 + gpe10:0 + gpe11:60 + gpe12:0 + gpe13:0 + gpe14:0 + gpe15:0 + gpe16:0 + gpe17:0 + gpe18:0 + gpe19:7 + gpe1A:0 + gpe1B:0 + gpe1C:0 + gpe1D:0 + gpe1E:0 + gpe1F:0 + gpe_all:241 + sci:241 + + sci - The total number of times the ACPI SCI + has claimed an interrupt. + + gpe_all - count of SCI caused by GPEs. + + gpeXX - count for individual GPE source + + ff_gbl_lock - Global Lock + + ff_pmtimer - PM Timer + + ff_pwr_btn - Power Button + + ff_rt_clk - Real Time Clock + + ff_slp_btn - Sleep Button + + error - an interrupt that can't be accounted for above. + + Root has permission to clear any of these counters. Eg. + # echo 0 > gpe11 + + All counters can be cleared by clearing the total "sci": + # echo 0 > sci + + None of these counters has an effect on the function + of the system, they are simply statistics.
drivers/acpi/events/evevent.c +1 -1
@@ -259,7 +259,7 @@ u32 acpi_ev_fixed_event_detect(void) enable_bit_mask)) {/* Found an active (signalled) event */ - +acpi_os_fixed_event_count (i); int_status |=acpi_ev_fixed_event_dispatch ((u32 ) i); } }
drivers/acpi/events/evgpe.c +1 -1
@@ -618,7 +618,7 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number)ACPI_FUNCTION_TRACE (ev_gpe_dispatch); - acpi_gpe_count++; +acpi_os_gpe_count (gpe_number);/* * If edge-triggered, clear the GPE status bit now. Note that
drivers/acpi/osl.c +11 -1
@@ -332,7 +332,15 @@ acpi_os_table_override(struct acpi_table_header * existing_table,static irqreturn_t acpi_irq (int irq,void *dev_id) { -return (*acpi_irq_handler) (acpi_irq_context) ?IRQ_HANDLED :IRQ_NONE ; +u32 handled; + + handled = (*acpi_irq_handler) (acpi_irq_context); + +if (handled) { + acpi_irq_handled++; +return IRQ_HANDLED ; + }else +return IRQ_NONE ; } acpi_status
@@ -341,6 +349,8 @@ acpi_os_install_interrupt_handler(u32 gsi, acpi_osd_handler handler, {unsigned int irq; +acpi_irq_stats_init (); +/* * Ignore the GSI from the core, and use the value in our copy of the * FADT. It may not be the same if an interrupt source override exists
drivers/acpi/system.c +208 -0
220 lines not on this page · raw message
drivers/acpi/utilities/utglobal.c +0 -2
@@ -671,7 +671,6 @@ void acpi_ut_init_globals(void)/* GPE support */ - acpi_gpe_count =0 ; acpi_gbl_gpe_xrupt_list_head =NULL ; acpi_gbl_gpe_fadt_blocks[0 ] =NULL ; acpi_gbl_gpe_fadt_blocks[1 ] =NULL ;
@@ -735,4 +734,3 @@ void acpi_ut_init_globals(void)ACPI_EXPORT_SYMBOL (acpi_dbg_level)ACPI_EXPORT_SYMBOL (acpi_dbg_layer) - ACPI_EXPORT_SYMBOL(acpi_gpe_count)
include/acpi/acglobal.h +0 -4
@@ -117,10 +117,6 @@ extern u32 acpi_dbg_layer;extern u32 acpi_gbl_nesting_level; -/* Event counters */ - -ACPI_EXTERN u32 acpi_gpe_count; -/* Support for dynamic control method tracing mechanism */ ACPI_EXTERN u32 acpi_gbl_original_dbg_level;
include/acpi/acpiosxf.h +3 -0
@@ -181,6 +181,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); +void acpi_os_fixed_event_count (u32 fixed_event_number); +/* * Threads and Scheduling */
include/linux/acpi.h +2 -0
@@ -115,7 +115,9 @@ int acpi_unmap_lsapic(int cpu);int acpi_register_ioapic (acpi_handle handle,u64 phys_addr,u32 gsi_base);int acpi_unregister_ioapic (acpi_handle handle,u32 gsi_base); +void acpi_irq_stats_init (void ); +extern u32 acpi_irq_handled;extern int acpi_mp_config;extern struct acpi_mcfg_allocation *pci_mmcfg_config;
Signature · 1 line
1.5.4.23.gef5b9
Quoted 11 lines · Len Brown
Thanks for the reply, Greg.
If these counters are not always available by default, then I've lost most of their value for supporting systems in the field.
Plus, I think I can live with just the individual sysfs files, given Bjorn's "grep . *" tip.
So if I follow the rules, do you think it is okay to put these stats in sysfs? In the hopes the answer is "yes", I'll reply with a refreshed patch
Sure, one value per file is fine. I'll be glad to review a patch like that, with a Documentation/ABI/ entry :)
thanks,
greg k-h
Re: [PATCH] ACPI: create /sys/firmware/acpi/interrupts/ (v2)
In reply to Len BrownQuoted 6 lines · Len Brown
From: Len Brown <[email protected]>
See
Documentation/ABI/testing/sysfs-firmware-acpiInspired-by Luming Yu <[email protected]>Signed-off-by Len Brown <[email protected]>
Looks good to me, nice job. And thanks for the documentation file.