Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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: 88 additions & 0 deletions cmd/plugins/balloons/policy/balloons-policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ const (
balloonKey = "balloon." + PolicyName + "." + kubernetes.ResmgrKeyNamespace
// hideHyperthreadsKey is a pod annotation key for pod/container-specific hyperthread allowance.
hideHyperthreadsKey = "hide-hyperthreads." + kubernetes.ResmgrKeyNamespace
// schedulingClassKey is a pod annotation key for pod/container-specific scheduling class.
schedulingClassKey = "scheduling-class." + kubernetes.ResmgrKeyNamespace
// reservedBalloonDefName is the name in the reserved balloon definition.
reservedBalloonDefName = "reserved"
// defaultBalloonDefName is the name in the default balloon definition.
Expand Down Expand Up @@ -1509,6 +1511,7 @@ func (p *balloons) applyBalloonDef(balloons *[]*Balloon, blnDef *BalloonDef, fre
func (p *balloons) validateConfig(bpoptions *BalloonsOptions) error {
seenNames := map[string]struct{}{}
undefinedLoadClasses := map[string]struct{}{}
undefinedSchedulingClasses := map[string]struct{}{}
compositeBlnDefs := map[string]*BalloonDef{}
for _, blnDef := range bpoptions.BalloonDefs {
if blnDef.Name == "" {
Expand Down Expand Up @@ -1581,6 +1584,9 @@ func (p *balloons) validateConfig(bpoptions *BalloonsOptions) error {
for _, load := range blnDef.Loads {
undefinedLoadClasses[load] = struct{}{}
}
if blnDef.SchedulingClass != "" {
undefinedSchedulingClasses[blnDef.SchedulingClass] = struct{}{}
}
}
for lcIndex, loadClass := range bpoptions.LoadClasses {
delete(undefinedLoadClasses, loadClass.Name)
Expand All @@ -1594,6 +1600,12 @@ func (p *balloons) validateConfig(bpoptions *BalloonsOptions) error {
if len(undefinedLoadClasses) > 0 {
return balloonsError("loads defined in balloonTypes but missing from loadClasses: %v", undefinedLoadClasses)
}
for _, schedClass := range bpoptions.SchedulingClasses {
delete(undefinedSchedulingClasses, schedClass.Name)
}
if len(undefinedSchedulingClasses) > 0 {
return balloonsError("schedulingClass(es) defined in balloonTypes but missing from schedulingClasses: %v", undefinedSchedulingClasses)
}
var circularCheck func(name string, seen map[string]int) error
circularCheck = func(name string, seen map[string]int) error {
if seen[name] > 0 {
Expand Down Expand Up @@ -2124,13 +2136,89 @@ func (bln *Balloon) updateGroups(c cache.Container, delta int) {
}
}

// applyProcessScheduling configures container's scheduling and IO priorities
func applyProcessScheduling(c cache.Container, sc *SchedulingClass) {
if sc == nil {
return
}
log.Debug(" - applying scheduling class %q to %s", sc.Name, c.PrettyName())
if sc.Policy != "" {
if pol, err := sc.Policy.ToNRI(); err == nil {
c.SetSchedulingPolicy(pol)
log.Debug(" - scheduling policy %q (%s)", sc.Policy, pol)
} else {
log.Debug(" - invalid scheduling policy %q in scheduling class %q: %v", sc.Policy, sc.Name, err)
}
}
if sc.Priority != nil {
c.SetSchedulingPriority(int32(*sc.Priority))
log.Debug(" - scheduling priority %d", *sc.Priority)
}
if len(sc.Flags) > 0 {
if flags, err := sc.Flags.ToNRI(); err == nil {
c.SetSchedulingFlags(flags)
log.Debug(" - scheduling flags %q", sc.Flags)
} else {
log.Debug(" - invalid scheduling flags %q in scheduling class %q: %v", sc.Flags, sc.Name, err)
}
}
if sc.Nice != nil {
c.SetSchedulingNice(int32(*sc.Nice))
log.Debug(" - nice value %d", *sc.Nice)
}
if sc.Runtime != nil {
c.SetSchedulingRuntime(*sc.Runtime)
log.Debug(" - scheduling runtime %d", *sc.Runtime)
}
if sc.Deadline != nil {
c.SetSchedulingDeadline(*sc.Deadline)
log.Debug(" - scheduling deadline %d", *sc.Deadline)
}
if sc.Period != nil {
c.SetSchedulingPeriod(*sc.Period)
log.Debug(" - scheduling period %d", *sc.Period)
}
if sc.IOClass != "" {
if ioClass, err := sc.IOClass.ToNRI(); err == nil {
c.SetSchedulingIOClass(ioClass)
log.Debug(" - IO class %q", sc.IOClass)
} else {
log.Debug(" - invalid IO class %q in scheduling class %q: %v", sc.IOClass, sc.Name, err)
}
}
if sc.IOPriority != nil {
c.SetSchedulingIOPriority(int32(*sc.IOPriority))
log.Debug(" - IO priority %d", *sc.IOPriority)
}
}

func (p *balloons) applyProcessProperties(c cache.Container, bln *Balloon) {
effSc := bln.Def.SchedulingClass
if annSc, annExists := c.GetEffectiveAnnotation(schedulingClassKey); annExists {
if annSc != effSc {
log.Debug(" - container %s overrides balloon scheduling class %q with annotation %q",
c.PrettyName(), effSc, annSc)
}
effSc = annSc
}
if effSc != "" {
for _, sc := range p.bpoptions.SchedulingClasses {
if sc.Name == effSc {
applyProcessScheduling(c, sc)
break
}
}
}
}

// assignContainer adds a container to a balloon
func (p *balloons) assignContainer(c cache.Container, bln *Balloon) {
log.Info("assigning container %s to balloon %s", c.PrettyName(), bln)
podID := c.GetPodID()
bln.PodIDs[podID] = append(bln.PodIDs[podID], c.GetID())
bln.updateGroups(c, 1)
p.updatePinning(bln)
p.applyProcessProperties(c, bln)
}

// dismissContainer removes a container from a balloon
Expand Down
1 change: 1 addition & 0 deletions cmd/plugins/balloons/policy/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ type (
BalloonsOptions = cfgapi.Config
BalloonDef = cfgapi.BalloonDef
LoadClass = cfgapi.LoadClass
SchedulingClass = cfgapi.SchedulingClass
CPUTopologyLevel = cfgapi.CPUTopologyLevel
)

Expand Down
27 changes: 27 additions & 0 deletions cmd/plugins/topology-aware/policy/mocks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,33 @@ func (m *mockContainer) SetMemoryLimit(int64) {
func (m *mockContainer) SetMemorySwap(int64) {
panic("unimplemented")
}
func (m *mockContainer) SetSchedulingPolicy(nri.LinuxSchedulerPolicy) {
panic("unimplemented")
}
func (m *mockContainer) SetSchedulingNice(int32) {
panic("unimplemented")
}
func (m *mockContainer) SetSchedulingPriority(int32) {
panic("unimplemented")
}
func (m *mockContainer) SetSchedulingFlags([]nri.LinuxSchedulerFlag) {
panic("unimplemented")
}
func (m *mockContainer) SetSchedulingRuntime(uint64) {
panic("unimplemented")
}
func (m *mockContainer) SetSchedulingDeadline(uint64) {
panic("unimplemented")
}
func (m *mockContainer) SetSchedulingPeriod(uint64) {
panic("unimplemented")
}
func (m *mockContainer) SetSchedulingIOClass(nri.IOPrioClass) {
panic("unimplemented")
}
func (m *mockContainer) SetSchedulingIOPriority(int32) {
panic("unimplemented")
}
func (m *mockContainer) GetPendingAdjustment() *nri.ContainerAdjustment {
panic("unimplemented")
}
Expand Down
94 changes: 94 additions & 0 deletions config/crd/bases/config.nri_balloonspolicies.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,14 @@ spec:
placed on separate balloons. The default is false: prefer
placing containers of a pod to the same balloon(s).
type: boolean
schedulingClass:
description: |-
SchedulingClass is the name of the scheduling class from
which default Linux scheduling and IO priority parameters
are applied on new containers created in these
balloons. Parameters for the class are specified in the
schedulingClasses list.
type: string
shareIdleCPUsInSame:
description: |-
ShareIdleCpusInSame <topology-level>: if there are idle
Expand Down Expand Up @@ -964,6 +972,92 @@ spec:
type: string
description: Reserved (CPU) resources for kube-system namespace.
type: object
schedulingClasses:
description: |-
SchedulingClasses specify scheduling classes available in
balloon types.
items:
description: |-
SchedulingClass specifies the default Linux scheduling and IO
priority parameters for containers assigned into this class.
properties:
deadline:
description: Deadline is the Linux SCHED_DEADLINE deadline value
to use (in microseconds).
format: int64
type: integer
flags:
description: |-
Flags is a list of Linux scheduling flags to set.
SCHED_FLAG_<ORIG_NAME> translates to <orig-name> etc.
enum:
- reset-on-fork
- reclaim
- dl-overrun
- keep-policy
- keep-params
- util-clamp-min
- util-clamp-max
items:
type: string
type: array
ioClass:
description: |-
IOClass is the IO scheduling class to use.
IOPRIO_CLASS_<NAME> translates to <name>.
Refer to ioprio_set(2) and ionice(1) for details.
enum:
- none
- rt
- be
- idle
type: string
ioPriority:
description: |-
IOPriority is the IO priority within the selected IO class to use.
Valid range depends on the selected class.
Refer to ionice(1) for details.
type: integer
name:
description: Name of the scheduling class.
type: string
nice:
description: Nice is the Linux nice value to use.
type: integer
period:
description: Period is the Linux SCHED_DEADLINE period value
to use (in microseconds).
format: int64
type: integer
policy:
description: |-
Policy is the Linux scheduling policy to use.
SCHED_<NAME> translates to <name> etc.
enum:
- none
- other
- fifo
- rr
- batch
- iso
- idle
- deadline
type: string
priority:
description: |-
Priority is the Linux scheduling priority to use.
Valid range depends on the selected policy.
Refer to sched_setscheduler(2) for details.
type: integer
runtime:
description: Runtime is the Linux SCHED_DEADLINE runtime value
to use (in microseconds).
format: int64
type: integer
required:
- name
type: object
type: array
showContainersInNrt:
description: |-
ShowContainersInNrt controls whether containers in balloons
Expand Down
94 changes: 94 additions & 0 deletions deployment/helm/balloons/crds/config.nri_balloonspolicies.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,14 @@ spec:
placed on separate balloons. The default is false: prefer
placing containers of a pod to the same balloon(s).
type: boolean
schedulingClass:
description: |-
SchedulingClass is the name of the scheduling class from
which default Linux scheduling and IO priority parameters
are applied on new containers created in these
balloons. Parameters for the class are specified in the
schedulingClasses list.
type: string
shareIdleCPUsInSame:
description: |-
ShareIdleCpusInSame <topology-level>: if there are idle
Expand Down Expand Up @@ -964,6 +972,92 @@ spec:
type: string
description: Reserved (CPU) resources for kube-system namespace.
type: object
schedulingClasses:
description: |-
SchedulingClasses specify scheduling classes available in
balloon types.
items:
description: |-
SchedulingClass specifies the default Linux scheduling and IO
priority parameters for containers assigned into this class.
properties:
deadline:
description: Deadline is the Linux SCHED_DEADLINE deadline value
to use (in microseconds).
format: int64
type: integer
flags:
description: |-
Flags is a list of Linux scheduling flags to set.
SCHED_FLAG_<ORIG_NAME> translates to <orig-name> etc.
enum:
- reset-on-fork
- reclaim
- dl-overrun
- keep-policy
- keep-params
- util-clamp-min
- util-clamp-max
items:
type: string
type: array
ioClass:
description: |-
IOClass is the IO scheduling class to use.
IOPRIO_CLASS_<NAME> translates to <name>.
Refer to ioprio_set(2) and ionice(1) for details.
enum:
- none
- rt
- be
- idle
type: string
ioPriority:
description: |-
IOPriority is the IO priority within the selected IO class to use.
Valid range depends on the selected class.
Refer to ionice(1) for details.
type: integer
name:
description: Name of the scheduling class.
type: string
nice:
description: Nice is the Linux nice value to use.
type: integer
period:
description: Period is the Linux SCHED_DEADLINE period value
to use (in microseconds).
format: int64
type: integer
policy:
description: |-
Policy is the Linux scheduling policy to use.
SCHED_<NAME> translates to <name> etc.
enum:
- none
- other
- fifo
- rr
- batch
- iso
- idle
- deadline
type: string
priority:
description: |-
Priority is the Linux scheduling priority to use.
Valid range depends on the selected policy.
Refer to sched_setscheduler(2) for details.
type: integer
runtime:
description: Runtime is the Linux SCHED_DEADLINE runtime value
to use (in microseconds).
format: int64
type: integer
required:
- name
type: object
type: array
showContainersInNrt:
description: |-
ShowContainersInNrt controls whether containers in balloons
Expand Down
Loading