in pkg/exporter/probe/tracesoftirq/tracesoftirq.go [233:299]
func (p *softirqProbe) perfLoop() {
for {
record, err := p.perfReader.Read()
if err != nil {
if errors.Is(err, ringbuf.ErrClosed) {
log.Errorf("%s received signal, exiting..", probeName)
return
}
log.Warnf("%s failed reading from reader, err: %v", probeName, err)
continue
}
if record.LostSamples != 0 {
log.Warnf("%s perf event ring buffer full, drop: %d", probeName, record.LostSamples)
continue
}
var event bpfInspSoftirqEventT
if err := binary.Read(bytes.NewBuffer(record.RawSample), binary.LittleEndian, &event); err != nil {
log.Errorf("%s failed parsing event, err: %v", probeName, err)
continue
}
evt := &probe.Event{
Timestamp: time.Now().UnixNano(),
Labels: []probe.Label{
{
Name: "type",
Value: convertIrqType(event.VecNr),
},
},
}
/*
#define PHASE_SCHED 1
#define PHASE_EXCUTE 2
*/
switch event.Phase {
case 1:
evt.Type = "SOFTIRQ_SCHED_SLOW"
p.updateMetrics(SOFTIRQ_SCHED_SLOW, event.VecNr)
if event.Latency > 100_000_000 {
evt.Type = "SOFTIRQ_SCHED_100MS"
p.updateMetrics(SOFTIRQ_SCHED_100MS, event.VecNr)
}
case 2:
evt.Type = "SOFTIRQ_EXCUTE_SLOW"
p.updateMetrics(SOFTIRQ_EXCUTE_SLOW, event.VecNr)
if event.Latency > 100_000_000 {
evt.Type = "SOFTIRQ_EXCUTE_100MS"
p.updateMetrics(SOFTIRQ_EXCUTE_100MS, event.VecNr)
}
default:
log.Infof("%s failed parsing event, phase: %d", probeName, event.Phase)
continue
}
evt.Message = fmt.Sprintf("cpu=%d pid=%d latency=%s ", event.Cpu, event.Pid, bpfutil.GetHumanTimes(event.Latency))
if filterIrqEvent(p.eventProbeIrqTypes, event.VecNr) && p.sink != nil {
log.Debugf("%s sink event %s", probeName, util.ToJSONString(evt))
p.sink <- evt
}
}
}