Skip to content

Commit

Permalink
Fix initialization in perf collector when using multiple CPUs (#1665)
Browse files Browse the repository at this point in the history
* Fix initialization in perf collector when using multiple CPUs

Signed-off-by: Daniel Hodges <hodges.daniel.scott@gmail.com>
  • Loading branch information
hodgesds committed Apr 17, 2020
1 parent 4135c00 commit 44357ed
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 2 deletions.
3 changes: 3 additions & 0 deletions collector/perf_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,18 +135,21 @@ func NewPerfCollector(logger log.Logger) (Collector, error) {
return nil, err
}
collector.perfHwProfilers[cpu] = &hwProf
collector.hwProfilerCPUMap[&hwProf] = cpu

swProf := perf.NewSoftwareProfiler(-1, cpu)
if err := swProf.Start(); err != nil {
return nil, err
}
collector.perfSwProfilers[cpu] = &swProf
collector.swProfilerCPUMap[&swProf] = cpu

cacheProf := perf.NewCacheProfiler(-1, cpu)
if err := cacheProf.Start(); err != nil {
return nil, err
}
collector.perfCacheProfilers[cpu] = &cacheProf
collector.cacheProfilerCPUMap[&cacheProf] = cpu
}

collector.desc = map[string]*prometheus.Desc{
Expand Down
65 changes: 63 additions & 2 deletions collector/perf_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,18 @@
package collector

import (
"github.com/go-kit/kit/log"
"io/ioutil"
"runtime"
"strconv"
"strings"
"testing"

"github.com/go-kit/kit/log"

"github.com/prometheus/client_golang/prometheus"
)

func TestPerfCollector(t *testing.T) {
func canTestPerf(t *testing.T) {
paranoidBytes, err := ioutil.ReadFile("/proc/sys/kernel/perf_event_paranoid")
if err != nil {
t.Skip("Procfs not mounted, skipping perf tests")
Expand All @@ -38,6 +40,10 @@ func TestPerfCollector(t *testing.T) {
if paranoid >= 1 {
t.Skip("Skipping perf tests, set perf_event_paranoid to 0")
}
}

func TestPerfCollector(t *testing.T) {
canTestPerf(t)
collector, err := NewPerfCollector(log.NewNopLogger())
if err != nil {
t.Fatal(err)
Expand All @@ -55,6 +61,61 @@ func TestPerfCollector(t *testing.T) {
}
}

func TestPerfCollectorStride(t *testing.T) {
canTestPerf(t)

tests := []struct {
name string
flag string
exCpus []int
}{
{
name: "valid single cpu",
flag: "1",
exCpus: []int{1},
},
{
name: "valid range cpus",
flag: "1-5",
exCpus: []int{1, 2, 3, 4, 5},
},
{
name: "valid stride",
flag: "1-8:2",
exCpus: []int{1, 3, 5, 7},
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
ncpu := runtime.NumCPU()
for _, cpu := range test.exCpus {
if cpu > ncpu {
t.Skipf("Skipping test because runtime.NumCPU < %d", cpu)
}
}
perfCPUsFlag = &test.flag
collector, err := NewPerfCollector(log.NewNopLogger())
if err != nil {
t.Fatal(err)
}

c := collector.(*perfCollector)
for _, cpu := range test.exCpus {
if _, ok := c.perfHwProfilers[cpu]; !ok {
t.Fatalf("Expected CPU %v in hardware profilers", cpu)
}
if _, ok := c.perfSwProfilers[cpu]; !ok {
t.Fatalf("Expected CPU %v in software profilers", cpu)
}
if _, ok := c.perfCacheProfilers[cpu]; !ok {
t.Fatalf("Expected CPU %v in cache profilers", cpu)
}
}
})
}
}

func TestPerfCPUFlagToCPUs(t *testing.T) {
tests := []struct {
name string
Expand Down

0 comments on commit 44357ed

Please sign in to comment.