Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 87 additions & 1 deletion cmd/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"math"
"os"
"perfspect/internal/common"
"perfspect/internal/cpudb"
"perfspect/internal/progress"
"perfspect/internal/report"
"perfspect/internal/script"
Expand Down Expand Up @@ -156,7 +157,7 @@ func getFlagGroups() []common.FlagGroup {
},
{
Name: flagElcName,
Help: "set Efficiency Latency Control (SRF and GNR) (" + strings.Join(elcOptions, ", ") + ")",
Help: "set Efficiency Latency Control (" + strings.Join(elcOptions, ", ") + ")",
},
}
groups := []common.FlagGroup{}
Expand Down Expand Up @@ -202,6 +203,83 @@ func validateFlags(cmd *cobra.Command, args []string) error {
return nil
}

type flagUarch struct {
flagName string
supportedUarch []string // empty means all are supported
}

// define supported uarch for each flag
var supportedUarchs = []flagUarch{
{
flagName: flagCoresName,
supportedUarch: []string{},
},
{
flagName: flagLlcSizeName,
supportedUarch: []string{"HSX", "BDX", "SKX", "CLX", "CPX", "ICX", "SPR", "EMR"},
},
{
flagName: flagAllCoreMaxFrequencyName,
supportedUarch: []string{"HSX", "BDX", "SKX", "CLX", "CPX", "ICX", "SPR", "EMR", "SRF", "GNR"},
},
{
flagName: flagUncoreMaxFrequencyName,
supportedUarch: []string{"HSX", "BDX", "SKX", "CLX", "CPX", "ICX", "SPR", "EMR", "SRF", "GNR"},
},
{
flagName: flagUncoreMinFrequencyName,
supportedUarch: []string{"HSX", "BDX", "SKX", "CLX", "CPX", "ICX", "SPR", "EMR", "SRF", "GNR"},
},
{
flagName: flagPowerName,
supportedUarch: []string{"HSX", "BDX", "SKX", "CLX", "CPX", "ICX", "SPR", "EMR", "SRF", "GNR"},
},
{
flagName: flagEpbName,
supportedUarch: []string{"HSX", "BDX", "SKX", "CLX", "CPX", "ICX", "SPR", "EMR", "SRF", "GNR"},
},
{
flagName: flagEppName,
supportedUarch: []string{"HSX", "BDX", "SKX", "CLX", "CPX", "ICX", "SPR", "EMR", "SRF", "GNR"},
},
{
flagName: flagGovernorName,
supportedUarch: []string{"HSX", "BDX", "SKX", "CLX", "CPX", "ICX", "SPR", "EMR", "SRF", "GNR"},
},
{
flagName: flagElcName,
supportedUarch: []string{"SRF", "GNR"},
},
}

func validateFlagsForTarget(cmd *cobra.Command, myTarget target.Target) error {
CPUdb := cpudb.NewCPUDB()
var family, model, stepping string
var err error
if family, err = myTarget.GetFamily(); err != nil {
return err
}
if model, err = myTarget.GetModel(); err != nil {
return err
}
if stepping, err = myTarget.GetStepping(); err != nil {
return err
}

cpu, err := CPUdb.GetCPU(family, model, stepping, "", "", "")
if err != nil {
return err
}
for _, flag := range supportedUarchs {
if cmd.Flags().Lookup(flag.flagName).Changed {
if len(flag.supportedUarch) != 0 && !util.StringInList(cpu.MicroArchitecture, flag.supportedUarch) {
return fmt.Errorf("%s flag not supported on %s microarchitecture", flag.flagName, cpu.MicroArchitecture)
}
}
}
return nil
}

func runCmd(cmd *cobra.Command, args []string) error {
// appContext is the application context that holds common data and resources.
appContext := cmd.Context().Value(common.AppContext{}).(common.AppContext)
Expand Down Expand Up @@ -230,6 +308,14 @@ func runCmd(cmd *cobra.Command, args []string) error {
cmd.SilenceUsage = true
return err
}
for _, myTarget := range myTargets {
if err = validateFlagsForTarget(cmd, myTarget); err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
slog.Error(err.Error())
cmd.SilenceUsage = true
return err
}
}
// create a temporary directory on each target
for _, myTarget := range myTargets {
targetTempRoot, _ := cmd.Flags().GetString(common.FlagTargetTempDirName)
Expand Down
30 changes: 30 additions & 0 deletions internal/target/target.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ type Target interface {
// It returns a string representing the model and any error that occurred.
GetModel() (model string, err error)

// GetStepping returns the stepping of the target system's CPU.
// It returns a string representing the stepping and any error that occurred.
GetStepping() (stepping string, err error)

// GetName returns the name of the target system.
// It returns a string representing the host.
GetName() (name string)
Expand Down Expand Up @@ -119,6 +123,7 @@ type LocalTarget struct {
arch string
family string
model string
stepping string
userPath string
canElevate int // zero indicates unknown, 1 indicates yes, -1 indicates no
}
Expand All @@ -135,6 +140,7 @@ type RemoteTarget struct {
arch string
family string
model string
stepping string
userPath string
canElevate int
}
Expand Down Expand Up @@ -260,6 +266,20 @@ func (t *RemoteTarget) GetModel() (family string, err error) {
return t.model, err
}

func (t *LocalTarget) GetStepping() (stepping string, err error) {
if t.stepping == "" {
t.stepping, err = getStepping(t)
}
return t.stepping, err
}

func (t *RemoteTarget) GetStepping() (stepping string, err error) {
if t.stepping == "" {
t.stepping, err = getStepping(t)
}
return t.stepping, err
}

// CreateTempDirectory creates a temporary directory under the specified root directory.
// It returns the path of the created temporary directory and any error encountered.
func (t *LocalTarget) CreateTempDirectory(rootDir string) (tempDir string, err error) {
Expand Down Expand Up @@ -781,6 +801,16 @@ func getModel(t Target) (model string, err error) {
return
}

func getStepping(t Target) (stepping string, err error) {
cmd := exec.Command("bash", "-c", "lscpu | grep -i stepping: | awk '{print $NF}'")
stepping, _, _, err = t.RunCommand(cmd, 0, true)
if err != nil {
return
}
stepping = strings.TrimSpace(stepping)
return
}

func installLkms(t Target, lkms []string) (installedLkms []string, err error) {
if !t.CanElevatePrivileges() {
err = fmt.Errorf("can't elevate privileges; elevated privileges required to install lkms")
Expand Down
Loading