mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-16 23:29:21 +00:00
KEP-4540: Add CPUManager policy option strict-cpu-reservation
Signed-off-by: Jing Zhang <jing.c.zhang.ext@nokia.com>
This commit is contained in:
parent
be8ea98a5c
commit
0365cf4b20
@ -33,6 +33,7 @@ const (
|
||||
DistributeCPUsAcrossNUMAOption string = "distribute-cpus-across-numa"
|
||||
AlignBySocketOption string = "align-by-socket"
|
||||
DistributeCPUsAcrossCoresOption string = "distribute-cpus-across-cores"
|
||||
StrictCPUReservationOption string = "strict-cpu-reservation"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -40,6 +41,7 @@ var (
|
||||
DistributeCPUsAcrossNUMAOption,
|
||||
AlignBySocketOption,
|
||||
DistributeCPUsAcrossCoresOption,
|
||||
StrictCPUReservationOption,
|
||||
)
|
||||
betaOptions = sets.New[string](
|
||||
FullPCPUsOnlyOption,
|
||||
@ -86,6 +88,8 @@ type StaticPolicyOptions struct {
|
||||
// cpus (HT) on different physical core.
|
||||
// This is a preferred policy so do not throw error if they have to packed in one physical core.
|
||||
DistributeCPUsAcrossCores bool
|
||||
// Flag to remove reserved cores from the list of available cores
|
||||
StrictCPUReservation bool
|
||||
}
|
||||
|
||||
// NewStaticPolicyOptions creates a StaticPolicyOptions struct from the user configuration.
|
||||
@ -121,7 +125,12 @@ func NewStaticPolicyOptions(policyOptions map[string]string) (StaticPolicyOption
|
||||
return opts, fmt.Errorf("bad value for option %q: %w", name, err)
|
||||
}
|
||||
opts.DistributeCPUsAcrossCores = optValue
|
||||
|
||||
case StrictCPUReservationOption:
|
||||
optValue, err := strconv.ParseBool(value)
|
||||
if err != nil {
|
||||
return opts, fmt.Errorf("bad value for option %q: %w", name, err)
|
||||
}
|
||||
opts.StrictCPUReservation = optValue
|
||||
default:
|
||||
// this should never be reached, we already detect unknown options,
|
||||
// but we keep it as further safety.
|
||||
|
@ -195,14 +195,19 @@ func (p *staticPolicy) validateState(s state.State) error {
|
||||
tmpAssignments := s.GetCPUAssignments()
|
||||
tmpDefaultCPUset := s.GetDefaultCPUSet()
|
||||
|
||||
allCPUs := p.topology.CPUDetails.CPUs()
|
||||
if p.options.StrictCPUReservation {
|
||||
allCPUs = allCPUs.Difference(p.reservedCPUs)
|
||||
}
|
||||
|
||||
// Default cpuset cannot be empty when assignments exist
|
||||
if tmpDefaultCPUset.IsEmpty() {
|
||||
if len(tmpAssignments) != 0 {
|
||||
return fmt.Errorf("default cpuset cannot be empty")
|
||||
}
|
||||
// state is empty initialize
|
||||
allCPUs := p.topology.CPUDetails.CPUs()
|
||||
s.SetDefaultCPUSet(allCPUs)
|
||||
klog.InfoS("Static policy initialized", "defaultCPUSet", allCPUs)
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -210,9 +215,16 @@ func (p *staticPolicy) validateState(s state.State) error {
|
||||
// 1. Check if the reserved cpuset is not part of default cpuset because:
|
||||
// - kube/system reserved have changed (increased) - may lead to some containers not being able to start
|
||||
// - user tampered with file
|
||||
if !p.reservedCPUs.Intersection(tmpDefaultCPUset).Equals(p.reservedCPUs) {
|
||||
return fmt.Errorf("not all reserved cpus: \"%s\" are present in defaultCpuSet: \"%s\"",
|
||||
p.reservedCPUs.String(), tmpDefaultCPUset.String())
|
||||
if p.options.StrictCPUReservation {
|
||||
if !p.reservedCPUs.Intersection(tmpDefaultCPUset).IsEmpty() {
|
||||
return fmt.Errorf("some of strictly reserved cpus: \"%s\" are present in defaultCpuSet: \"%s\"",
|
||||
p.reservedCPUs.Intersection(tmpDefaultCPUset).String(), tmpDefaultCPUset.String())
|
||||
}
|
||||
} else {
|
||||
if !p.reservedCPUs.Intersection(tmpDefaultCPUset).Equals(p.reservedCPUs) {
|
||||
return fmt.Errorf("not all reserved cpus: \"%s\" are present in defaultCpuSet: \"%s\"",
|
||||
p.reservedCPUs.String(), tmpDefaultCPUset.String())
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Check if state for static policy is consistent
|
||||
@ -235,15 +247,20 @@ func (p *staticPolicy) validateState(s state.State) error {
|
||||
// the set of CPUs stored in the state.
|
||||
totalKnownCPUs := tmpDefaultCPUset.Clone()
|
||||
tmpCPUSets := []cpuset.CPUSet{}
|
||||
tmpAllCPUs := p.topology.CPUDetails.CPUs()
|
||||
for pod := range tmpAssignments {
|
||||
for _, cset := range tmpAssignments[pod] {
|
||||
tmpCPUSets = append(tmpCPUSets, cset)
|
||||
}
|
||||
}
|
||||
totalKnownCPUs = totalKnownCPUs.Union(tmpCPUSets...)
|
||||
if !totalKnownCPUs.Equals(p.topology.CPUDetails.CPUs()) {
|
||||
if p.options.StrictCPUReservation {
|
||||
tmpAllCPUs = tmpAllCPUs.Difference(p.reservedCPUs)
|
||||
}
|
||||
if !totalKnownCPUs.Equals(tmpAllCPUs) {
|
||||
return fmt.Errorf("current set of available CPUs \"%s\" doesn't match with CPUs in state \"%s\"",
|
||||
p.topology.CPUDetails.CPUs().String(), totalKnownCPUs.String())
|
||||
tmpAllCPUs.String(), totalKnownCPUs.String())
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
|
Loading…
Reference in New Issue
Block a user