...
1
16
17 package cpumanager
18
19 import (
20 "fmt"
21 "strconv"
22
23 "k8s.io/apimachinery/pkg/util/sets"
24 utilfeature "k8s.io/apiserver/pkg/util/feature"
25 kubefeatures "k8s.io/kubernetes/pkg/features"
26 "k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/topology"
27 "k8s.io/kubernetes/pkg/kubelet/cm/topologymanager"
28 )
29
30
31 const (
32 FullPCPUsOnlyOption string = "full-pcpus-only"
33 DistributeCPUsAcrossNUMAOption string = "distribute-cpus-across-numa"
34 AlignBySocketOption string = "align-by-socket"
35 )
36
37 var (
38 alphaOptions = sets.New[string](
39 DistributeCPUsAcrossNUMAOption,
40 AlignBySocketOption,
41 )
42 betaOptions = sets.New[string](
43 FullPCPUsOnlyOption,
44 )
45 stableOptions = sets.New[string]()
46 )
47
48
49
50 func CheckPolicyOptionAvailable(option string) error {
51 if !alphaOptions.Has(option) && !betaOptions.Has(option) && !stableOptions.Has(option) {
52 return fmt.Errorf("unknown CPU Manager Policy option: %q", option)
53 }
54
55 if alphaOptions.Has(option) && !utilfeature.DefaultFeatureGate.Enabled(kubefeatures.CPUManagerPolicyAlphaOptions) {
56 return fmt.Errorf("CPU Manager Policy Alpha-level Options not enabled, but option %q provided", option)
57 }
58
59 if betaOptions.Has(option) && !utilfeature.DefaultFeatureGate.Enabled(kubefeatures.CPUManagerPolicyBetaOptions) {
60 return fmt.Errorf("CPU Manager Policy Beta-level Options not enabled, but option %q provided", option)
61 }
62
63 return nil
64 }
65
66
67 type StaticPolicyOptions struct {
68
69
70
71
72
73
74
75
76 FullPhysicalCPUsOnly bool
77
78
79 DistributeCPUsAcrossNUMA bool
80
81
82 AlignBySocket bool
83 }
84
85
86 func NewStaticPolicyOptions(policyOptions map[string]string) (StaticPolicyOptions, error) {
87 opts := StaticPolicyOptions{}
88 for name, value := range policyOptions {
89 if err := CheckPolicyOptionAvailable(name); err != nil {
90 return opts, err
91 }
92
93 switch name {
94 case FullPCPUsOnlyOption:
95 optValue, err := strconv.ParseBool(value)
96 if err != nil {
97 return opts, fmt.Errorf("bad value for option %q: %w", name, err)
98 }
99 opts.FullPhysicalCPUsOnly = optValue
100 case DistributeCPUsAcrossNUMAOption:
101 optValue, err := strconv.ParseBool(value)
102 if err != nil {
103 return opts, fmt.Errorf("bad value for option %q: %w", name, err)
104 }
105 opts.DistributeCPUsAcrossNUMA = optValue
106 case AlignBySocketOption:
107 optValue, err := strconv.ParseBool(value)
108 if err != nil {
109 return opts, fmt.Errorf("bad value for option %q: %w", name, err)
110 }
111 opts.AlignBySocket = optValue
112 default:
113
114
115 return opts, fmt.Errorf("unsupported cpumanager option: %q (%s)", name, value)
116 }
117 }
118 return opts, nil
119 }
120
121
122 func ValidateStaticPolicyOptions(opts StaticPolicyOptions, topology *topology.CPUTopology, topologyManager topologymanager.Store) error {
123 if opts.AlignBySocket {
124
125 if topologyManager.GetPolicy().Name() == topologymanager.PolicySingleNumaNode {
126 return fmt.Errorf("Topolgy manager %s policy is incompatible with CPUManager %s policy option", topologymanager.PolicySingleNumaNode, AlignBySocketOption)
127 }
128
129 if topology.NumSockets > topology.NumNUMANodes {
130 return fmt.Errorf("Align by socket is not compatible with hardware where number of sockets are more than number of NUMA")
131 }
132 }
133 return nil
134 }
135
View as plain text