Home > OS >  /proc/interrupts - Read in c shows no IPIs
/proc/interrupts - Read in c shows no IPIs

Time:09-23

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 
  • Related