Skip to content

Commit

Permalink
First attempt at collecting at least *some* perf events
Browse files Browse the repository at this point in the history
Signed-off-by: Maciej "Iwan" Iwanowski <maciej.iwanowski@intel.com>
  • Loading branch information
Maciej "Iwan" Iwanowski committed Mar 17, 2020
1 parent 3de9c89 commit 71e90c5
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 4 deletions.
3 changes: 3 additions & 0 deletions manager/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ type containerData struct {

// nvidiaCollector updates stats for Nvidia GPUs attached to the container.
nvidiaCollector stats.Collector

// perfCollector updates stats for perf_event cgroup controller.
perfCollector stats.Collector
}

// jitter returns a time.Duration between duration and duration + maxFactor * duration,
Expand Down
10 changes: 10 additions & 0 deletions manager/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -943,6 +943,16 @@ func (m *manager) createContainerLocked(containerName string, watchSource watche
klog.V(4).Infof("GPU metrics may be unavailable/incomplete for container %q: %v", cont.info.Name, err)
}
}

perfCgroupPath, err := handler.GetCgroupPath("perf_event")
if err != nil {
klog.Warningf("Error getting perf_event cgroup path: %q", err)
} else {
cont.perfCollector, err = m.perfManager.GetCollector(perfCgroupPath)
if err != nil {
klog.V(4).Infof("perf_event metrics will not be available for container %q: %q", cont.info.Name, err)
}
}
}

// Add collectors
Expand Down
50 changes: 48 additions & 2 deletions perf/collector.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,57 @@
// Collector of perf events for a container.
package perf

import v1 "github.com/google/cadvisor/info/v1"
import (
"fmt"
v1 "github.com/google/cadvisor/info/v1"
"golang.org/x/sys/unix"
"k8s.io/klog"
"os"
"unsafe"
)

type collector struct {
cgroupPath string
events Events
fileDescriptors []int
}

func (c *collector) UpdateStats(stats *v1.ContainerStats) error {
panic("implement me")
klog.Infof("Attempting to update perf_event stats from cgroup %q", c.cgroupPath)
return nil
}

func (c *collector) setup() error {
for _, event := range c.events.NonGrouped {
klog.Infof("Setting up non-grouped perf event %#v", event)
length := len(event.Config)
size := uint32(unsafe.Sizeof(unix.PerfEventAttr{}))

config := &unix.PerfEventAttr{
Type: event.Type,
Config: event.Config[0],
Size: size,
}
if length >= 2 {
config.Ext1 = event.Config[1]
}
if length == 3 {
config.Ext2 = event.Config[2]
}
klog.Infof("perf_event_attr struct prepared: %#v", config)

cgroupFd, err := os.Open(c.cgroupPath)
if err != nil {
klog.Errorf("Cannot open cgroup directory %q: %q", c.cgroupPath, err)
return fmt.Errorf("cannot open cgroup directory %q: %q", c.cgroupPath, err)
}
pid, cpu, groupFd, flags := int(cgroupFd.Fd()), -1, -1, unix.PERF_FLAG_PID_CGROUP
fd, err := unix.PerfEventOpen(config, pid, cpu, groupFd, flags)
if err != nil {
klog.Errorf("Setting up perf event %#v failed: %q", event, err)
return fmt.Errorf("setting up perf event %#v failed: %q", event, err)
}
c.fileDescriptors = append(c.fileDescriptors, fd)
}
return nil
}
10 changes: 8 additions & 2 deletions perf/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@ func (m *manager) Destroy() {
// Do nothing
}

func (m *manager) GetCollector(deviceCgroup string) (stats.Collector, error) {
return nil, nil
func (m *manager) GetCollector(cgroupPath string) (stats.Collector, error) {
collector := &collector{cgroupPath: cgroupPath, events: m.events}
err := collector.setup()
if err != nil {
klog.Errorf("Unable to setup monitoring for perf_event cgroup %q: %q", cgroupPath, err)
return nil, fmt.Errorf("unable to setup monitoring for perf_event cgroup %q: %q", cgroupPath, err)
}
return collector, nil
}

0 comments on commit 71e90c5

Please sign in to comment.