From 4e5eb04a1abf49ae3d38e11fbdfcc01934acb96b Mon Sep 17 00:00:00 2001 From: Michael Turek Date: Mon, 30 Oct 2023 10:44:46 -0400 Subject: [PATCH] Power VS: Control SMT level with machineconfig Co-authored-by: Rafael F. --- .../install.openshift.io_installconfigs.yaml | 12 ++++ pkg/asset/machines/machineconfig/powersmt.go | 70 +++++++++++++++++++ pkg/asset/machines/master.go | 9 +++ pkg/asset/machines/worker.go | 9 +++ pkg/types/powervs/machinepools.go | 8 +++ pkg/types/powervs/validation/machinepool.go | 8 +++ 6 files changed, 116 insertions(+) create mode 100644 pkg/asset/machines/machineconfig/powersmt.go diff --git a/data/data/install.openshift.io_installconfigs.yaml b/data/data/install.openshift.io_installconfigs.yaml index e8ab7c7c9f6..2c061707c47 100644 --- a/data/data/install.openshift.io_installconfigs.yaml +++ b/data/data/install.openshift.io_installconfigs.yaml @@ -979,6 +979,10 @@ spec: description: Processors defines the processing units for the instance. x-kubernetes-int-or-string: true + smtLevel: + description: SMTLevel specifies the level of SMT to set + the control plane and worker nodes to. + type: string sysType: description: SysType defines the system type for instance. type: string @@ -1906,6 +1910,10 @@ spec: description: Processors defines the processing units for the instance. x-kubernetes-int-or-string: true + smtLevel: + description: SMTLevel specifies the level of SMT to set the + control plane and worker nodes to. + type: string sysType: description: SysType defines the system type for instance. type: string @@ -4152,6 +4160,10 @@ spec: description: Processors defines the processing units for the instance. x-kubernetes-int-or-string: true + smtLevel: + description: SMTLevel specifies the level of SMT to set the + control plane and worker nodes to. + type: string sysType: description: SysType defines the system type for instance. type: string diff --git a/pkg/asset/machines/machineconfig/powersmt.go b/pkg/asset/machines/machineconfig/powersmt.go new file mode 100644 index 00000000000..63b9a67cfca --- /dev/null +++ b/pkg/asset/machines/machineconfig/powersmt.go @@ -0,0 +1,70 @@ +package machineconfig + +import ( + "fmt" + + ignutil "github.com/coreos/ignition/v2/config/util" + igntypes "github.com/coreos/ignition/v2/config/v3_2/types" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/openshift/installer/pkg/asset/ignition" + mcfgv1 "github.com/openshift/machine-config-operator/pkg/apis/machineconfiguration.openshift.io/v1" +) + +// ForPowerSMT sets the SMT level for Power machines. +func ForPowerSMT(role string, smtLevel string) (*mcfgv1.MachineConfig, error) { + powerSMTUnit, err := createPowerSMTUnit(smtLevel) + if err != nil { + return nil, err + } + + ignConfig := igntypes.Config{ + Ignition: igntypes.Ignition{ + Version: igntypes.MaxVersion.String(), + }, + Systemd: igntypes.Systemd{ + Units: []igntypes.Unit{ + { + Contents: &powerSMTUnit, + Name: fmt.Sprintf("99-%s-powersmt.service", role), + Enabled: ignutil.BoolToPtr(true), + }, + }, + }, + } + + rawExt, err := ignition.ConvertToRawExtension(ignConfig) + if err != nil { + return nil, err + } + + return &mcfgv1.MachineConfig{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "machineconfiguration.openshift.io/v1", + Kind: "MachineConfig", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("99-%s-powersmt", role), + Labels: map[string]string{ + "machineconfiguration.openshift.io/role": role, + }, + }, + Spec: mcfgv1.MachineConfigSpec{ + Config: rawExt, + }, + }, nil +} + +func createPowerSMTUnit(smtLevel string) (string, error) { + unit := `[Unit] +Description=Set SMT +After=network-online.target +Before= crio.service +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/usr/sbin/ppc64_cpu --smt=%s +[Install] +WantedBy=multi-user.target` + return fmt.Sprintf(unit, smtLevel), nil +} diff --git a/pkg/asset/machines/master.go b/pkg/asset/machines/master.go index ca7ff4cf47f..131316dfac5 100644 --- a/pkg/asset/machines/master.go +++ b/pkg/asset/machines/master.go @@ -553,6 +553,15 @@ func (m *Master) Generate(dependencies asset.Parents) error { return errors.Wrap(err, "failed to create ignition for Multipath enabled for master machines") } machineConfigs = append(machineConfigs, ignMultipath) + + // set SMT level if specified for powervs. + if pool.Platform.PowerVS.SMTLevel != "" { + ignPowerSMT, err := machineconfig.ForPowerSMT("master", pool.Platform.PowerVS.SMTLevel) + if err != nil { + return errors.Wrap(err, "failed to create ignition for Power SMT for master machines") + } + machineConfigs = append(machineConfigs, ignPowerSMT) + } } // The maximum number of networks supported on ServiceNetwork is two, one IPv4 and one IPv6 network. // The cluster-network-operator handles the validation of this field. diff --git a/pkg/asset/machines/worker.go b/pkg/asset/machines/worker.go index 39ed23ae15d..12a8f433591 100644 --- a/pkg/asset/machines/worker.go +++ b/pkg/asset/machines/worker.go @@ -294,6 +294,15 @@ func (w *Worker) Generate(dependencies asset.Parents) error { return errors.Wrap(err, "failed to create ignition for multipath enabled for worker machines") } machineConfigs = append(machineConfigs, ignMultipath) + + // set SMT level if specified for powervs. + if pool.Platform.PowerVS != nil && pool.Platform.PowerVS.SMTLevel != "" { + ignPowerSMT, err := machineconfig.ForPowerSMT("worker", pool.Platform.PowerVS.SMTLevel) + if err != nil { + return errors.Wrap(err, "failed to create ignition for Power SMT for worker machines") + } + machineConfigs = append(machineConfigs, ignPowerSMT) + } } // The maximum number of networks supported on ServiceNetwork is two, one IPv4 and one IPv6 network. // The cluster-network-operator handles the validation of this field. diff --git a/pkg/types/powervs/machinepools.go b/pkg/types/powervs/machinepools.go index d34127bbe03..f8dedac0d3b 100644 --- a/pkg/types/powervs/machinepools.go +++ b/pkg/types/powervs/machinepools.go @@ -30,6 +30,11 @@ type MachinePool struct { // +optional ProcType machinev1.PowerVSProcessorType `json:"procType,omitempty"` + // SMTLevel specifies the level of SMT to set the control plane and worker nodes to. + // + // +optional + SMTLevel string `json:"smtLevel,omitempty"` + // SysType defines the system type for instance. // // +optional @@ -53,6 +58,9 @@ func (a *MachinePool) Set(required *MachinePool) { if required.ProcType != "" { a.ProcType = required.ProcType } + if required.SMTLevel != "" { + a.SMTLevel = required.SMTLevel + } if required.SysType != "" { a.SysType = required.SysType } diff --git a/pkg/types/powervs/validation/machinepool.go b/pkg/types/powervs/validation/machinepool.go index 4f0a9137b36..9a6567bd4ba 100644 --- a/pkg/types/powervs/validation/machinepool.go +++ b/pkg/types/powervs/validation/machinepool.go @@ -1,6 +1,7 @@ package validation import ( + "fmt" "regexp" "strconv" "strings" @@ -13,6 +14,8 @@ import ( "github.com/openshift/installer/pkg/types/powervs" ) +var validSMTLevels = sets.New[string]("1", "2", "3", "4", "5", "6", "7", "8", "on", "off") + // ValidateMachinePool checks that the specified machine pool is valid. func ValidateMachinePool(p *powervs.MachinePool, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} @@ -70,6 +73,11 @@ func ValidateMachinePool(p *powervs.MachinePool, fldPath *field.Path) field.Erro } } + // Validate SMTLevel + if p.SMTLevel != "" && !validSMTLevels.Has(p.SMTLevel) { + allErrs = append(allErrs, field.Invalid(fldPath.Child("smtLevel"), p.SMTLevel, fmt.Sprintf("Valid SMT Levels are %s", sets.List(validSMTLevels)))) + } + // Validate SysType if p.SysType != "" { const sysTypeRegex = `^(?:e980|s922(-.*|))$`