/proc/interrupts - 读入 c 显示没有 IPI
/proc/interrupts - Read in c shows no IPIs
当我cat /proc/interrupts
时,我还可以看到系统内部中断(如doc中所述),例如核心上发生的所有 IPI。
但是,当我用C读/proc/interrupts的内容时,这些额外的行是没有的。例如。此代码:
#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;
}
提供与 cat 相同的输出,除了最后缺少有关 IPI 的行。为什么我的 C 代码无法读取 IPI 行,我该如何解决?
编辑:添加两种不同方法的输出
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
您正在寻找的是 IPI 中断向量计数的 RES/CAL
行。
典型的 SMP Linux(v3.10) 具有很少的 IPI 中断向量,如下所示和相应的处理程序。一个是重新调度,另外两个是使接收 CPU 到 运行 函数通过。正如我们所见,所有三个向量事件都有各自的计数器,并在过程级别显示为 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, "%10u ", 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, "%10u ", irq_stats(j)->irq_call_count -
irq_stats(j)->irq_tlb_count);
seq_printf(p, " Function call interrupts\n");
#endif
解决方案是连续两次从打开的文件描述符中读取,即使在第一次迭代时没有读取完整的缓冲区。 cat
也是这样做的。因此,以下代码将产生所需的输出:
#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;
}
当我cat /proc/interrupts
时,我还可以看到系统内部中断(如doc中所述),例如核心上发生的所有 IPI。
但是,当我用C读/proc/interrupts的内容时,这些额外的行是没有的。例如。此代码:
#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;
}
提供与 cat 相同的输出,除了最后缺少有关 IPI 的行。为什么我的 C 代码无法读取 IPI 行,我该如何解决?
编辑:添加两种不同方法的输出
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
您正在寻找的是 IPI 中断向量计数的 RES/CAL
行。
典型的 SMP Linux(v3.10) 具有很少的 IPI 中断向量,如下所示和相应的处理程序。一个是重新调度,另外两个是使接收 CPU 到 运行 函数通过。正如我们所见,所有三个向量事件都有各自的计数器,并在过程级别显示为 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, "%10u ", 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, "%10u ", irq_stats(j)->irq_call_count -
irq_stats(j)->irq_tlb_count);
seq_printf(p, " Function call interrupts\n");
#endif
解决方案是连续两次从打开的文件描述符中读取,即使在第一次迭代时没有读取完整的缓冲区。 cat
也是这样做的。因此,以下代码将产生所需的输出:
#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;
}