Search code examples
linuxinterruptprocfs

/proc/interrupts - Read in c shows no IPIs


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

Solution

  • 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;
    }