When I cat /proc/interrupts
, I can also see system internal interrupts (as described in the doc), e.g. all the IPIs occurring on the cores.
However, when I read the content of /proc/interrupts in C, these additional lines are not there. E.g. this code:
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char **argv)
{
int source, n;
unsigned char buffer[8192];
source = open("/proc/interrupts", O_RDONLY);
n=read(source, buffer, 8192);
close(source);
buffer[n] = 0;
printf("%d chars in /proc/interrupts:\n", n);
printf("%s", buffer);
return 0;
}
delivers the same output as cat except for the lines about IPIs missing at the end. Why are the IPI lines not read by my C code and how can I fix that?
EDIT: Adding the output of the two different approaches
uuser@mpsoc:~/git/rt-benchmarking/ARM64/tif$ cat /proc/interrupts
CPU0 CPU1 CPU2 CPU3
3: 64464514 20153532 359399 132413 GICv2 30 Level arch_timer
6: 0 0 0 0 GICv2 67 Level zynqmp_ipi
7: 0 0 0 0 GICv2 175 Level arm-pmu
8: 0 0 0 0 GICv2 176 Level arm-pmu
9: 0 0 0 0 GICv2 177 Level arm-pmu
10: 0 0 0 0 GICv2 178 Level arm-pmu
13: 0 0 0 0 GICv2 156 Level zynqmp-dma
14: 0 0 0 0 GICv2 157 Level zynqmp-dma
15: 0 0 0 0 GICv2 158 Level zynqmp-dma
16: 0 0 0 0 GICv2 159 Level zynqmp-dma
17: 0 0 0 0 GICv2 160 Level zynqmp-dma
18: 0 0 0 0 GICv2 161 Level zynqmp-dma
19: 0 0 0 0 GICv2 162 Level zynqmp-dma
20: 0 0 0 0 GICv2 163 Level zynqmp-dma
22: 0 0 0 0 GICv2 109 Level zynqmp-dma
23: 0 0 0 0 GICv2 110 Level zynqmp-dma
24: 0 0 0 0 GICv2 111 Level zynqmp-dma
25: 0 0 0 0 GICv2 112 Level zynqmp-dma
26: 0 0 0 0 GICv2 113 Level zynqmp-dma
27: 0 0 0 0 GICv2 114 Level zynqmp-dma
28: 0 0 0 0 GICv2 115 Level zynqmp-dma
29: 0 0 0 0 GICv2 116 Level zynqmp-dma
30: 1 0 0 0 GICv2 144 Level fd070000.memory-controller
31: 0 0 0 0 GICv2 89 Level eth0, eth0
32: 9075012 0 0 0 GICv2 95 Level eth1, eth1
34: 0 0 0 0 GICv2 49 Level cdns-i2c
35: 0 0 0 0 GICv2 50 Level cdns-i2c
36: 0 0 0 0 GICv2 42 Level ff960000.memory-controller
37: 0 0 0 0 GICv2 57 Level axi-pmon, axi-pmon
38: 0 0 0 0 GICv2 155 Level axi-pmon, axi-pmon
39: 6215 0 0 0 GICv2 47 Level ff0f0000.spi
40: 0 0 0 0 GICv2 58 Level ffa60000.rtc
41: 0 0 0 0 GICv2 59 Level ffa60000.rtc
42: 674 0 0 0 GICv2 80 Level mmc0
43: 439018 0 0 0 GICv2 81 Level mmc1
44: 0 0 0 0 GICv2 51 Level ff040000.spi
45: 0 0 0 0 GICv2 52 Level ff050000.spi
46: 300 0 0 0 GICv2 53 Level xuartps
48: 0 0 0 0 GICv2 88 Level ams-irq
49: 12 0 0 0 GICv2 154 Level fd4c0000.dma
50: 0 0 0 0 GICv2 151 Level fd4a0000.zynqmp-display
51: 0 0 0 0 GICv2 97 Level xhci-hcd:usb1
IPI0: 2913422 5267435 34552519 34586268 Rescheduling interrupts
IPI1: 146402 147211 18371 29840 Function call interrupts
IPI2: 0 0 0 0 CPU stop interrupts
IPI3: 0 0 0 0 CPU stop (for crash dump) interrupts
IPI4: 0 0 0 0 Timer broadcast interrupts
IPI5: 28636 345 203 125 IRQ work interrupts
IPI6: 0 0 0 0 CPU wake-up interrupts
Err: 0
uuser@mpsoc:~/git/rt-benchmarking/ARM64/tif$ ./a.out
3626 chars in /proc/interrupts:
CPU0 CPU1 CPU2 CPU3
3: 64465302 20153650 359399 132413 GICv2 30 Level arch_timer
6: 0 0 0 0 GICv2 67 Level zynqmp_ipi
7: 0 0 0 0 GICv2 175 Level arm-pmu
8: 0 0 0 0 GICv2 176 Level arm-pmu
9: 0 0 0 0 GICv2 177 Level arm-pmu
10: 0 0 0 0 GICv2 178 Level arm-pmu
13: 0 0 0 0 GICv2 156 Level zynqmp-dma
14: 0 0 0 0 GICv2 157 Level zynqmp-dma
15: 0 0 0 0 GICv2 158 Level zynqmp-dma
16: 0 0 0 0 GICv2 159 Level zynqmp-dma
17: 0 0 0 0 GICv2 160 Level zynqmp-dma
18: 0 0 0 0 GICv2 161 Level zynqmp-dma
19: 0 0 0 0 GICv2 162 Level zynqmp-dma
20: 0 0 0 0 GICv2 163 Level zynqmp-dma
22: 0 0 0 0 GICv2 109 Level zynqmp-dma
23: 0 0 0 0 GICv2 110 Level zynqmp-dma
24: 0 0 0 0 GICv2 111 Level zynqmp-dma
25: 0 0 0 0 GICv2 112 Level zynqmp-dma
26: 0 0 0 0 GICv2 113 Level zynqmp-dma
27: 0 0 0 0 GICv2 114 Level zynqmp-dma
28: 0 0 0 0 GICv2 115 Level zynqmp-dma
29: 0 0 0 0 GICv2 116 Level zynqmp-dma
30: 1 0 0 0 GICv2 144 Level fd070000.memory-controller
31: 0 0 0 0 GICv2 89 Level eth0, eth0
32: 9075115 0 0 0 GICv2 95 Level eth1, eth1
34: 0 0 0 0 GICv2 49 Level cdns-i2c
35: 0 0 0 0 GICv2 50 Level cdns-i2c
36: 0 0 0 0 GICv2 42 Level ff960000.memory-controller
37: 0 0 0 0 GICv2 57 Level axi-pmon, axi-pmon
38: 0 0 0 0 GICv2 155 Level axi-pmon, axi-pmon
39: 6215 0 0 0 GICv2 47 Level ff0f0000.spi
40: 0 0 0 0 GICv2 58 Level ffa60000.rtc
41: 0 0 0 0 GICv2 59 Level ffa60000.rtc
42: 674 0 0 0 GICv2 80 Level mmc0
43: 439018 0 0 0 GICv2 81 Level mmc1
44: 0 0 0 0 GICv2 51 Level ff040000.spi
45: 0 0 0 0 GICv2 52 Level ff050000.spi
46: 300 0 0 0 GICv2 53 Level xuartps
48: 0 0 0 0 GICv2 88 Level ams-irq
49: 12 0 0 0 GICv2 154 Level fd4c0000.dma
50: 0 0 0 0 GICv2 151 Level fd4a0000.zynqmp-display
51: 0 0 0 0 GICv2 97 Level xhci-hcd:usb1
CodePudding user response:
The solution is reading from the open file descriptor twice in a row, even though not a full buffer was read at the first iteration. That's also how cat
does it. Therefore, the following code will produce the desired output:
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char **argv)
{
int source, n;
unsigned char buffer[8192];
source = open("/proc/interrupts", O_RDONLY);
for(int i = 0; i < 2; i )
{
n=read(source, buffer, 8192);
buffer[n] = 0;
printf("%d chars in /proc/interrupts:\n", n);
printf("%s", buffer);
}
close(source);
return 0;
}
CodePudding user response:
What you are looking is RES/CAL
rows for IPI interrupts vector counts.
Typical SMP Linux(v3.10) has few IPI interrupt vectors as shown below and corresponding handlers. One is rescheduling and other two are making receive CPUs to run functions passed. As we can see all three vectors events has respective counters and displayed in proc level as RES/CAL.
RES: 2714120 2132494 1806195 1827171 1204178 1184985 1135312 1194862 Rescheduling interrupts
CAL: 311349 239698 256054 260474 201761 185813 227458 186660 Function call interrupts
#define RESCHEDULE_VECTOR 0xfd
#define CALL_FUNCTION_VECTOR 0xfc
#define CALL_FUNCTION_SINGLE_VECTOR 0xfb
#ifdef CONFIG_SMP
apicinterrupt CALL_FUNCTION_SINGLE_VECTOR \
call_function_single_interrupt smp_call_function_single_interrupt
apicinterrupt CALL_FUNCTION_VECTOR \
call_function_interrupt smp_call_function_interrupt
apicinterrupt RESCHEDULE_VECTOR \
reschedule_interrupt smp_reschedule_interrupt
#endif
#ifdef CONFIG_SMP
unsigned int irq_resched_count;
unsigned int irq_call_count;
#endif
#ifdef CONFIG_SMP
seq_printf(p, "%*s: ", prec, "RES");
for_each_online_cpu(j)
seq_printf(p, "u ", irq_stats(j)->irq_resched_count);
seq_printf(p, " Rescheduling interrupts\n");
seq_printf(p, "%*s: ", prec, "CAL");
for_each_online_cpu(j)
seq_printf(p, "u ", irq_stats(j)->irq_call_count -
irq_stats(j)->irq_tlb_count);
seq_printf(p, " Function call interrupts\n");
#endif