Skip to content

Commit 7be3a4a

Browse files
dveedenoblitorum
authored andcommitted
interrupts_linux: Fix fields on aarch64 (prometheus#2631)
* interrupts_linux: Fix fields on aarch64 Fixes prometheus#2557 --------- Signed-off-by: Daniël van Eeden <[email protected]>
1 parent 9b69762 commit 7be3a4a

File tree

3 files changed

+113
-16
lines changed

3 files changed

+113
-16
lines changed
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
CPU0 CPU1 CPU2 CPU3 CPU4 CPU5 CPU6 CPU7
2+
10: 3287008667 3310445093 3301386305 3273132897 3368262064 3641875466 3360412019 3225020442 GICv3 27 Level arch_timer
3+
14: 7815 0 0 4 0 0 0 0 GICv3 37 Level ttyS0
4+
17: 0 0 0 0 0 0 0 0 GICv3 48 Edge ACPI:Ged
5+
18: 0 0 0 0 0 0 0 0 GICv3 49 Edge ACPI:Ged
6+
19: 0 0 0 0 0 0 0 0 GICv3 50 Edge ACPI:Ged
7+
20: 0 0 0 0 0 0 0 0 GICv3 51 Edge ACPI:Ged
8+
21: 0 0 0 0 0 0 0 0 GICv3 52 Edge ACPI:Ged
9+
22: 0 0 0 0 0 0 0 0 GICv3 53 Edge ACPI:Ged
10+
23: 0 0 0 0 0 0 0 0 GICv3 54 Edge ACPI:Ged
11+
24: 0 0 0 0 0 0 0 0 GICv3 55 Edge ACPI:Ged
12+
25: 0 0 0 0 0 0 0 0 GICv3 56 Edge ACPI:Ged
13+
26: 0 0 0 0 0 0 0 0 GICv3 57 Edge ACPI:Ged
14+
27: 0 0 0 0 0 0 0 0 GICv3 58 Edge ACPI:Ged
15+
28: 0 0 0 0 0 0 0 0 GICv3 59 Edge ACPI:Ged
16+
29: 0 0 0 0 0 0 0 0 GICv3 60 Edge ACPI:Ged
17+
30: 0 0 0 0 0 0 0 0 GICv3 61 Edge ACPI:Ged
18+
31: 0 0 0 0 0 0 0 0 GICv3 62 Edge ACPI:Ged
19+
32: 0 0 0 0 0 0 0 0 GICv3 63 Edge ACPI:Ged
20+
33: 0 0 0 0 0 0 0 0 GICv3 64 Edge ACPI:Ged
21+
34: 0 0 0 0 0 0 0 0 GICv3 65 Edge ACPI:Ged
22+
35: 0 0 0 0 0 0 0 0 GICv3 66 Edge ACPI:Ged
23+
36: 0 0 0 0 0 0 0 0 GICv3 67 Edge ACPI:Ged
24+
37: 0 0 0 0 0 0 0 0 GICv3 68 Edge ACPI:Ged
25+
38: 0 0 0 0 0 0 0 0 GICv3 69 Edge ACPI:Ged
26+
39: 0 0 0 0 0 0 0 0 GICv3 70 Edge ACPI:Ged
27+
40: 0 0 0 0 0 0 0 0 GICv3 71 Edge ACPI:Ged
28+
41: 0 0 0 0 0 0 0 0 GICv3 72 Edge ACPI:Ged
29+
42: 0 0 0 0 0 0 0 0 GICv3 73 Edge ACPI:Ged
30+
43: 0 0 0 0 0 0 0 0 GICv3 74 Edge ACPI:Ged
31+
44: 0 0 0 0 0 0 0 0 GICv3 75 Edge ACPI:Ged
32+
45: 0 0 0 0 0 0 0 0 GICv3 76 Edge ACPI:Ged
33+
46: 0 0 0 0 0 0 0 0 GICv3 77 Edge ACPI:Ged
34+
47: 0 0 0 0 0 0 0 0 GICv3 78 Edge ACPI:Ged
35+
48: 0 0 0 0 0 0 0 0 GICv3 79 Edge ACPI:Ged
36+
49: 0 0 0 0 0 0 0 0 GICv3 23 Level arm-pmu
37+
50: 0 0 0 0 0 0 0 0 ARMH0061:00 3 Edge ACPI:Event
38+
51: 13 0 0 20 4 0 0 0 ITS-MSI 65536 Edge nvme0q0
39+
52: 0 9 0 0 0 5 20 0 ITS-MSI 507904 Edge nvme1q0
40+
53: 129969327 0 0 0 0 0 0 0 ITS-MSI 65537 Edge nvme0q1
41+
54: 0 0 0 0 126913956 0 0 0 ITS-MSI 65538 Edge nvme0q2
42+
55: 0 199619844 0 0 0 0 0 0 ITS-MSI 507905 Edge nvme1q1
43+
56: 0 0 0 0 0 198494086 0 0 ITS-MSI 507906 Edge nvme1q2
44+
57: 0 0 51 0 0 32479308 0 0 ITS-MSI 81920 Edge ena-mgmnt@pci:0000:00:05.0
45+
58: 0 0 1195697946 437 0 0 0 0 ITS-MSI 81921 Edge eth0-Tx-Rx-0
46+
59: 0 0 0 2709937608 1619 0 0 0 ITS-MSI 81922 Edge eth0-Tx-Rx-1
47+
60: 0 1457922109 0 0 0 71 0 0 ITS-MSI 81923 Edge eth0-Tx-Rx-2
48+
61: 2052879736 0 0 0 0 0 124 0 ITS-MSI 81924 Edge eth0-Tx-Rx-3
49+
62: 0 0 0 0 0 0 2268695629 1530 ITS-MSI 81925 Edge eth0-Tx-Rx-4
50+
63: 50 0 0 0 0 0 0 1997799253 ITS-MSI 81926 Edge eth0-Tx-Rx-5
51+
64: 0 48 0 0 1238622585 0 0 0 ITS-MSI 81927 Edge eth0-Tx-Rx-6
52+
65: 0 0 47 0 0 0 0 1574978449 ITS-MSI 81928 Edge eth0-Tx-Rx-7
53+
IPI0:2768808080 2844211768 2878602432 2730576120 2723524623 3349096412 2717389879 2154252810 Rescheduling interrupts
54+
IPI1: 357815098 213258177 153713187 132890624 124746406 123498004 122386326 120728639 Function call interrupts
55+
IPI2: 0 0 0 0 0 0 0 0 CPU stop interrupts
56+
IPI3: 0 0 0 0 0 0 0 0 CPU stop (for crash dump) interrupts
57+
IPI4: 0 0 0 0 0 0 0 0 Timer broadcast interrupts
58+
IPI5: 0 0 0 0 0 0 0 0 IRQ work interrupts
59+
IPI6: 0 0 0 0 0 0 0 0 CPU wake-up interrupts
60+
Err: 0
61+

collector/interrupts_linux.go

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -77,22 +77,29 @@ func parseInterrupts(r io.Reader) (map[string]interrupt, error) {
7777
cpuNum := len(strings.Fields(scanner.Text())) // one header per cpu
7878

7979
for scanner.Scan() {
80-
parts := strings.Fields(scanner.Text())
81-
if len(parts) < cpuNum+2 { // irq + one column per cpu + details,
82-
continue // we ignore ERR and MIS for now
83-
}
84-
intName := parts[0][:len(parts[0])-1] // remove trailing :
85-
intr := interrupt{
86-
values: parts[1 : cpuNum+1],
87-
}
80+
// On aarch64 there can be zero space between the name/label
81+
// and the values, so we need to split on `:` before using
82+
// strings.Fields() to split on fields.
83+
group := strings.SplitN(scanner.Text(), ":", 2)
84+
if len(group) > 1 {
85+
parts := strings.Fields(group[1])
86+
87+
if len(parts) < cpuNum+1 { // irq + one column per cpu + details,
88+
continue // we ignore ERR and MIS for now
89+
}
90+
intName := strings.TrimLeft(group[0], " ")
91+
intr := interrupt{
92+
values: parts[0:cpuNum],
93+
}
8894

89-
if _, err := strconv.Atoi(intName); err == nil { // numeral interrupt
90-
intr.info = parts[cpuNum+1]
91-
intr.devices = strings.Join(parts[cpuNum+2:], " ")
92-
} else {
93-
intr.info = strings.Join(parts[cpuNum+1:], " ")
95+
if _, err := strconv.Atoi(intName); err == nil { // numeral interrupt
96+
intr.info = parts[cpuNum]
97+
intr.devices = strings.Join(parts[cpuNum+1:], " ")
98+
} else {
99+
intr.info = strings.Join(parts[cpuNum:], " ")
100+
}
101+
interrupts[intName] = intr
94102
}
95-
interrupts[intName] = intr
96103
}
97104

98105
return interrupts, scanner.Err()

collector/interrupts_linux_test.go

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,39 @@ func TestInterrupts(t *testing.T) {
3131
}
3232

3333
if want, got := "5031", interrupts["NMI"].values[1]; want != got {
34-
t.Errorf("want interrupts %s, got %s", want, got)
34+
t.Errorf("want interrupts value %s, got %s", want, got)
3535
}
3636

3737
if want, got := "4968", interrupts["NMI"].values[3]; want != got {
38-
t.Errorf("want interrupts %s, got %s", want, got)
38+
t.Errorf("want interrupts value %s, got %s", want, got)
39+
}
40+
41+
if want, got := "IR-IO-APIC-edge", interrupts["12"].info; want != got {
42+
t.Errorf("want interrupts info %s, got %s", want, got)
43+
}
44+
45+
if want, got := "i8042", interrupts["12"].devices; want != got {
46+
t.Errorf("want interrupts devices %s, got %s", want, got)
47+
}
48+
49+
}
50+
51+
// https://github.com/prometheus/node_exporter/issues/2557
52+
// On aarch64 the interrupts file can have zero spaces between the label of
53+
// the row and the first value if the value is large
54+
func TestInterruptsArm(t *testing.T) {
55+
file, err := os.Open("fixtures/proc/interrupts_aarch64")
56+
if err != nil {
57+
t.Fatal(err)
58+
}
59+
defer file.Close()
60+
61+
interrupts, err := parseInterrupts(file)
62+
if err != nil {
63+
t.Fatal(err)
64+
}
65+
66+
if _, ok := interrupts["IPI0"]; !ok {
67+
t.Errorf("IPI0 label not found in interrupts")
3968
}
4069
}

0 commit comments

Comments
 (0)