Skip to content

Commit

Permalink
powertelemetry version 1.0.1
Browse files Browse the repository at this point in the history
  • Loading branch information
ggalieroc committed Jan 8, 2024
1 parent 027daaf commit 28a68a6
Show file tree
Hide file tree
Showing 9 changed files with 547 additions and 86 deletions.
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.0.0
1.0.1
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ go 1.21
require (
github.com/intel/iaevents v1.1.0
github.com/jmhodges/clock v1.2.0
github.com/shirou/gopsutil/v3 v3.23.10
github.com/shirou/gopsutil/v3 v3.23.11
github.com/stretchr/testify v1.8.4
golang.org/x/sync v0.5.0
)
Expand All @@ -22,6 +22,6 @@ require (
github.com/tklauser/numcpus v0.6.1 // indirect
github.com/yusufpapurcu/wmi v1.2.3 // indirect
golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect
golang.org/x/sys v0.13.0 // indirect
golang.org/x/sys v0.15.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b h1:0LFwY6Q3gMACTjAbMZBjXAqTOzOwFaj2Ld6cjeQ7Rig=
github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
github.com/shirou/gopsutil/v3 v3.23.10 h1:/N42opWlYzegYaVkWejXWJpbzKv2JDy3mrgGzKsh9hM=
github.com/shirou/gopsutil/v3 v3.23.10/go.mod h1:JIE26kpucQi+innVlAUnIEOSBhBUkirr5b44yr55+WE=
github.com/shirou/gopsutil/v3 v3.23.11 h1:i3jP9NjCPUz7FiZKxlMnODZkdSIp2gnzfrvsu9CuWEQ=
github.com/shirou/gopsutil/v3 v3.23.11/go.mod h1:1FrWgea594Jp7qmjHUUPlJDTPgcsb9mGnXDxavtikzM=
github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU=
Expand All @@ -51,8 +51,8 @@ golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
Expand Down
42 changes: 40 additions & 2 deletions msr.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,14 @@ import (
"errors"
"fmt"
"io"
"math/big"
"os"
"path/filepath"
"regexp"
"strconv"
"time"

"github.com/intel/powertelemetry/internal/log"
)

const (
Expand Down Expand Up @@ -216,6 +219,9 @@ type msrRegWithStorage interface {
// the previous read operation.
getOffsetDeltas() map[uint32]uint64

// setOffsetDeltas sets the given map of offset key and delta offset values to the receiver.
setOffsetDeltas(offsets map[uint32]uint64)

// getTimestampDelta gets the timestamp delta between the last offset values reading operation
// and its previous reading operation.
getTimestampDelta() time.Duration
Expand Down Expand Up @@ -284,7 +290,7 @@ func (m *msrWithStorage) setOffsetDeltas(offsetDeltas map[uint32]uint64) {
// update performs reading operations along the offsets specified by the receiver. It updates
// last read offset values and delta offset values of the receiver.
func (m *msrWithStorage) update() error {
latest, err := m.readAll(m.offsets)
latest, err := m.msrReg.readAll(m.offsets)
if err != nil {
return err
}
Expand All @@ -296,7 +302,12 @@ func (m *msrWithStorage) update() error {
prev := m.getOffsetValues()
deltasMap := make(map[uint32]uint64, len(latest))
for offset := range latest {
deltasMap[offset] = latest[offset] - prev[offset]
if latest[offset] < prev[offset] {
deltasMap[offset] = 0
log.Warnf("A negative delta for the offset 0x%X and CPU ID %v", offset, m.msrReg.getCPUID())
} else {
deltasMap[offset] = latest[offset] - prev[offset]
}
}

m.setOffsetDeltas(deltasMap)
Expand All @@ -314,6 +325,7 @@ func (m *msrWithStorage) getTimestampDelta() time.Duration {
// MSR offset values, read and store multiple MSR offset values, and eventually provide the MSR delta
// offset values between latest and its previous reading operation.
type msrReaderWithStorage interface {
// initMsrMap initializes a map of CPU ID key and MSR register value with storage.
initMsrMap(cpuIDs []int, timeout time.Duration) error

// isMsrLoaded check if MSR kernel module is loaded.
Expand All @@ -328,6 +340,10 @@ type msrReaderWithStorage interface {
// getOffsetDeltas takes a CPU ID and returns MSR delta offset values between latest and its previous reading operation.
getOffsetDeltas(cpuID int) (map[uint32]uint64, error)

// scaleOffsetDeltas takes a CPU ID and a slice of msr offsets. It scales all offset deltas of the msr storage by multiplying
// each offset delta by the given factor f.
scaleOffsetDeltas(cpuID int, offsets []uint32, f *big.Float) error

// getTimestampDelta takes a CPU ID and returns the time interval between the last offset value reading operation
// and its previous reading operation.
getTimestampDelta(cpuID int) (time.Duration, error)
Expand Down Expand Up @@ -463,6 +479,28 @@ func (m *msrDataWithStorage) getOffsetDeltas(cpuID int) (map[uint32]uint64, erro
return reg.getOffsetDeltas(), nil
}

// scaleOffsetDeltas takes a CPU ID and a slice of msr offsets. It scales all offset deltas of the msr storage by multiplying
// each offset delta by the given factor f.
func (m *msrDataWithStorage) scaleOffsetDeltas(cpuID int, offsets []uint32, f *big.Float) error {
reg, ok := m.msrMap[cpuID]
if !ok {
return fmt.Errorf("could not find MSR register for CPU ID: %v", cpuID)
}

deltas := reg.getOffsetDeltas()
for _, offset := range offsets {
if v, ok := deltas[offset]; ok {
deltaBig := new(big.Float).SetUint64(v)
scaledDeltaBig := new(big.Float).Mul(deltaBig, f)
scaledDelta, _ := scaledDeltaBig.Uint64()
deltas[offset] = scaledDelta
}
}

reg.setOffsetDeltas(deltas)
return nil
}

// getTimestampDelta takes a CPU ID and returns the time interval between the last offset value reading
// operation and its previous reading operation.
func (m *msrDataWithStorage) getTimestampDelta(cpuID int) (time.Duration, error) {
Expand Down
84 changes: 84 additions & 0 deletions msr_mock_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// Copyright (C) 2023 Intel Corporation
// SPDX-License-Identifier: Apache-2.0

//go:build linux && amd64

package powertelemetry

import (
"math/big"
"time"

"github.com/stretchr/testify/mock"
)

// msrRegMock represents a mock for msr type. Implements msrReg interface.
type msrRegMock struct {
mock.Mock
}

func (m *msrRegMock) getPath() string {
args := m.Called()
return args.String(0)
}

func (m *msrRegMock) getCPUID() int {
args := m.Called()
return args.Int(0)
}

func (m *msrRegMock) read(offset uint32) (uint64, error) {
args := m.Called(offset)
return args.Get(0).(uint64), args.Error(1)
}

func (m *msrRegMock) readAll(offsets []uint32) (map[uint32]uint64, error) {
args := m.Called(offsets)
if args.Get(0) == nil {
return nil, args.Error(1)
}
return args.Get(0).(map[uint32]uint64), args.Error(1)
}

// msrMock represents a mock for msrDataWithStorage type. Implements msrReaderWithStorage interface.
type msrMock struct {
mock.Mock
}

func (m *msrMock) initMsrMap(cpuIDs []int, timeout time.Duration) error {
args := m.Called(cpuIDs, timeout)
return args.Error(0)
}

func (m *msrMock) read(offset uint32, cpuID int) (uint64, error) {
args := m.Called(offset, cpuID)
return args.Get(0).(uint64), args.Error(1)
}

func (m *msrMock) isMsrLoaded(modulesPath string) (bool, error) {
args := m.Called(modulesPath)
return args.Bool(0), args.Error(1)
}

func (m *msrMock) update(cpuID int) error {
args := m.Called(cpuID)
return args.Error(0)
}

func (m *msrMock) scaleOffsetDeltas(cpuID int, offsets []uint32, f *big.Float) error {
args := m.Called(cpuID, offsets, f)
return args.Error(0)
}

func (m *msrMock) getOffsetDeltas(cpuID int) (map[uint32]uint64, error) {
args := m.Called(cpuID)
if args.Get(0) == nil {
return nil, args.Error(1)
}
return args.Get(0).(map[uint32]uint64), args.Error(1)
}

func (m *msrMock) getTimestampDelta(cpuID int) (time.Duration, error) {
args := m.Called(cpuID)
return args.Get(0).(time.Duration), args.Error(1)
}
Loading

0 comments on commit 28a68a6

Please sign in to comment.