|
|
|
@ -37,12 +37,67 @@ const (
|
|
|
|
|
var ( |
|
|
|
|
perfCPUsFlag = kingpin.Flag("collector.perf.cpus", "List of CPUs from which perf metrics should be collected").Default("").String() |
|
|
|
|
perfTracepointFlag = kingpin.Flag("collector.perf.tracepoint", "perf tracepoint that should be collected").Strings() |
|
|
|
|
perfNoHwProfiler = kingpin.Flag("collector.perf.disable-hardware-profilers", "disable perf hardware profilers").Default("false").Bool() |
|
|
|
|
perfHwProfilerFlag = kingpin.Flag("collector.perf.hardware-profilers", "perf hardware profilers that should be collected").Strings() |
|
|
|
|
perfNoSwProfiler = kingpin.Flag("collector.perf.disable-software-profilers", "disable perf software profilers").Default("false").Bool() |
|
|
|
|
perfSwProfilerFlag = kingpin.Flag("collector.perf.software-profilers", "perf software profilers that should be collected").Strings() |
|
|
|
|
perfNoCaProfiler = kingpin.Flag("collector.perf.disable-cache-profilers", "disable perf cache profilers").Default("false").Bool() |
|
|
|
|
perfCaProfilerFlag = kingpin.Flag("collector.perf.cache-profilers", "perf cache profilers that should be collected").Strings() |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
func init() { |
|
|
|
|
registerCollector(perfSubsystem, defaultDisabled, NewPerfCollector) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var ( |
|
|
|
|
perfHardwareProfilerMap = map[string]perf.HardwareProfilerType{ |
|
|
|
|
"CpuCycles": perf.CpuCyclesProfiler, |
|
|
|
|
"CpuInstr": perf.CpuInstrProfiler, |
|
|
|
|
"CacheRef": perf.CacheRefProfiler, |
|
|
|
|
"CacheMisses": perf.CacheMissesProfiler, |
|
|
|
|
"BranchInstr": perf.BranchInstrProfiler, |
|
|
|
|
"BranchMisses": perf.BranchMissesProfiler, |
|
|
|
|
"StalledCyclesBackend": perf.StalledCyclesBackendProfiler, |
|
|
|
|
"StalledCyclesFrontend": perf.StalledCyclesFrontendProfiler, |
|
|
|
|
"RefCpuCycles": perf.RefCpuCyclesProfiler, |
|
|
|
|
// "BusCycles": perf.BusCyclesProfiler,
|
|
|
|
|
} |
|
|
|
|
perfSoftwareProfilerMap = map[string]perf.SoftwareProfilerType{ |
|
|
|
|
"PageFault": perf.PageFaultProfiler, |
|
|
|
|
"ContextSwitch": perf.ContextSwitchProfiler, |
|
|
|
|
"CpuMigration": perf.CpuMigrationProfiler, |
|
|
|
|
"MinorFault": perf.MinorFaultProfiler, |
|
|
|
|
"MajorFault": perf.MajorFaultProfiler, |
|
|
|
|
// "CpuClock": perf.CpuClockProfiler,
|
|
|
|
|
// "TaskClock": perf.TaskClockProfiler,
|
|
|
|
|
// "AlignFault": perf.AlignFaultProfiler,
|
|
|
|
|
// "EmuFault": perf.EmuFaultProfiler,
|
|
|
|
|
} |
|
|
|
|
perfCacheProfilerMap = map[string]perf.CacheProfilerType{ |
|
|
|
|
"L1DataReadHit": perf.L1DataReadHitProfiler, |
|
|
|
|
"L1DataReadMiss": perf.L1DataReadMissProfiler, |
|
|
|
|
"L1DataWriteHit": perf.L1DataWriteHitProfiler, |
|
|
|
|
"L1InstrReadMiss": perf.L1InstrReadMissProfiler, |
|
|
|
|
"LLReadHit": perf.LLReadHitProfiler, |
|
|
|
|
"LLReadMiss": perf.LLReadMissProfiler, |
|
|
|
|
"LLWriteHit": perf.LLWriteHitProfiler, |
|
|
|
|
"LLWriteMiss": perf.LLWriteMissProfiler, |
|
|
|
|
"InstrTLBReadHit": perf.InstrTLBReadHitProfiler, |
|
|
|
|
"InstrTLBReadMiss": perf.InstrTLBReadMissProfiler, |
|
|
|
|
"BPUReadHit": perf.BPUReadHitProfiler, |
|
|
|
|
"BPUReadMiss": perf.BPUReadMissProfiler, |
|
|
|
|
// "L1InstrReadHit": perf.L1InstrReadHitProfiler,
|
|
|
|
|
// "DataTLBReadHit": perf.DataTLBReadHitProfiler,
|
|
|
|
|
// "DataTLBReadMiss": perf.DataTLBReadMissProfiler,
|
|
|
|
|
// "DataTLBWriteHit": perf.DataTLBWriteHitProfiler,
|
|
|
|
|
// "DataTLBWriteMiss": perf.DataTLBWriteMissProfiler,
|
|
|
|
|
// "NodeCacheReadHit": perf.NodeCacheReadHitProfiler,
|
|
|
|
|
// "NodeCacheReadMiss": perf.NodeCacheReadMissProfiler,
|
|
|
|
|
// "NodeCacheWriteHit": perf.NodeCacheWriteHitProfiler,
|
|
|
|
|
// "NodeCacheWriteMiss": perf.NodeCacheWriteMissProfiler,
|
|
|
|
|
} |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
// perfTracepointFlagToTracepoints returns the set of configured tracepoints.
|
|
|
|
|
func perfTracepointFlagToTracepoints(tracepointsFlag []string) ([]*perfTracepoint, error) { |
|
|
|
|
tracepoints := make([]*perfTracepoint, len(tracepointsFlag)) |
|
|
|
@ -282,48 +337,82 @@ func NewPerfCollector(logger log.Logger) (Collector, error) {
|
|
|
|
|
collector.tracepointCollector = tracepointCollector |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Configure perf profilers
|
|
|
|
|
hardwareProfilers := perf.AllHardwareProfilers |
|
|
|
|
if *perfHwProfilerFlag != nil && len(*perfHwProfilerFlag) > 0 { |
|
|
|
|
// hardwareProfilers = 0
|
|
|
|
|
for _, hf := range *perfHwProfilerFlag { |
|
|
|
|
if v, ok := perfHardwareProfilerMap[hf]; ok { |
|
|
|
|
hardwareProfilers |= v |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
softwareProfilers := perf.AllSoftwareProfilers |
|
|
|
|
if *perfSwProfilerFlag != nil && len(*perfSwProfilerFlag) > 0 { |
|
|
|
|
// softwareProfilers = 0
|
|
|
|
|
for _, sf := range *perfSwProfilerFlag { |
|
|
|
|
if v, ok := perfSoftwareProfilerMap[sf]; ok { |
|
|
|
|
softwareProfilers |= v |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
cacheProfilers := perf.L1DataReadHitProfiler | perf.L1DataReadMissProfiler | perf.L1DataWriteHitProfiler | perf.L1InstrReadMissProfiler | perf.InstrTLBReadHitProfiler | perf.InstrTLBReadMissProfiler | perf.LLReadHitProfiler | perf.LLReadMissProfiler | perf.LLWriteHitProfiler | perf.LLWriteMissProfiler | perf.BPUReadHitProfiler | perf.BPUReadMissProfiler |
|
|
|
|
if *perfCaProfilerFlag != nil && len(*perfCaProfilerFlag) > 0 { |
|
|
|
|
cacheProfilers = 0 |
|
|
|
|
for _, cf := range *perfCaProfilerFlag { |
|
|
|
|
if v, ok := perfCacheProfilerMap[cf]; ok { |
|
|
|
|
cacheProfilers |= v |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Configure all profilers for the specified CPUs.
|
|
|
|
|
for _, cpu := range cpus { |
|
|
|
|
// Use -1 to profile all processes on the CPU, see:
|
|
|
|
|
// man perf_event_open
|
|
|
|
|
hwProf, err := perf.NewHardwareProfiler( |
|
|
|
|
-1, |
|
|
|
|
cpu, |
|
|
|
|
perf.AllHardwareProfilers, |
|
|
|
|
) |
|
|
|
|
if err != nil && !hwProf.HasProfilers() { |
|
|
|
|
return nil, err |
|
|
|
|
} |
|
|
|
|
if err := hwProf.Start(); err != nil { |
|
|
|
|
return nil, err |
|
|
|
|
if !*perfNoHwProfiler { |
|
|
|
|
hwProf, err := perf.NewHardwareProfiler( |
|
|
|
|
-1, |
|
|
|
|
cpu, |
|
|
|
|
hardwareProfilers, |
|
|
|
|
) |
|
|
|
|
if err != nil && !hwProf.HasProfilers() { |
|
|
|
|
return nil, err |
|
|
|
|
} |
|
|
|
|
if err := hwProf.Start(); err != nil { |
|
|
|
|
return nil, err |
|
|
|
|
} |
|
|
|
|
collector.perfHwProfilers[cpu] = &hwProf |
|
|
|
|
collector.hwProfilerCPUMap[&hwProf] = cpu |
|
|
|
|
} |
|
|
|
|
collector.perfHwProfilers[cpu] = &hwProf |
|
|
|
|
collector.hwProfilerCPUMap[&hwProf] = cpu |
|
|
|
|
|
|
|
|
|
swProf, err := perf.NewSoftwareProfiler(-1, cpu, perf.AllSoftwareProfilers) |
|
|
|
|
if err != nil && !swProf.HasProfilers() { |
|
|
|
|
return nil, err |
|
|
|
|
} |
|
|
|
|
if err := swProf.Start(); err != nil { |
|
|
|
|
return nil, err |
|
|
|
|
if !*perfNoSwProfiler { |
|
|
|
|
swProf, err := perf.NewSoftwareProfiler(-1, cpu, softwareProfilers) |
|
|
|
|
if err != nil && !swProf.HasProfilers() { |
|
|
|
|
return nil, err |
|
|
|
|
} |
|
|
|
|
if err := swProf.Start(); err != nil { |
|
|
|
|
return nil, err |
|
|
|
|
} |
|
|
|
|
collector.perfSwProfilers[cpu] = &swProf |
|
|
|
|
collector.swProfilerCPUMap[&swProf] = cpu |
|
|
|
|
} |
|
|
|
|
collector.perfSwProfilers[cpu] = &swProf |
|
|
|
|
collector.swProfilerCPUMap[&swProf] = cpu |
|
|
|
|
|
|
|
|
|
cacheProfilers := perf.L1DataReadHitProfiler & perf.L1DataReadMissProfiler & perf.L1DataWriteHitProfiler & perf.L1InstrReadMissProfiler & perf.InstrTLBReadHitProfiler & perf.InstrTLBReadMissProfiler & perf.LLReadHitProfiler & perf.LLReadMissProfiler & perf.LLWriteHitProfiler & perf.LLWriteMissProfiler & perf.BPUReadHitProfiler & perf.BPUReadMissProfiler |
|
|
|
|
cacheProf, err := perf.NewCacheProfiler( |
|
|
|
|
-1, |
|
|
|
|
cpu, |
|
|
|
|
cacheProfilers, |
|
|
|
|
) |
|
|
|
|
if err != nil && !cacheProf.HasProfilers() { |
|
|
|
|
return nil, err |
|
|
|
|
} |
|
|
|
|
if err := cacheProf.Start(); err != nil { |
|
|
|
|
return nil, err |
|
|
|
|
if !*perfNoCaProfiler { |
|
|
|
|
cacheProf, err := perf.NewCacheProfiler( |
|
|
|
|
-1, |
|
|
|
|
cpu, |
|
|
|
|
cacheProfilers, |
|
|
|
|
) |
|
|
|
|
if err != nil && !cacheProf.HasProfilers() { |
|
|
|
|
return nil, err |
|
|
|
|
} |
|
|
|
|
if err := cacheProf.Start(); err != nil { |
|
|
|
|
return nil, err |
|
|
|
|
} |
|
|
|
|
collector.perfCacheProfilers[cpu] = &cacheProf |
|
|
|
|
collector.cacheProfilerCPUMap[&cacheProf] = cpu |
|
|
|
|
} |
|
|
|
|
collector.perfCacheProfilers[cpu] = &cacheProf |
|
|
|
|
collector.cacheProfilerCPUMap[&cacheProf] = cpu |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
collector.desc = map[string]*prometheus.Desc{ |
|
|
|
|