Skip to content

Commit 26674c5

Browse files
committed
device-injector: add scheduling policy adjustment.
Signed-off-by: Krisztian Litkey <[email protected]>
1 parent 2cdbf29 commit 26674c5

File tree

1 file changed

+99
-0
lines changed

1 file changed

+99
-0
lines changed

plugins/device-injector/device-injector.go

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ const (
4747
ioPrioKey = "io-priority.noderesource.dev"
4848
// Deprecated: Prefix of the key used for I/O priority adjustment.
4949
oldIoPrioKey = "io-priority.nri.io"
50+
// Prefix of the key used for scheduler attribute adjustment.
51+
schedulerKey = "scheduling-policy.noderesource.dev"
52+
// Deprecated: Prefix of the key used for scheduler attribute adjustment.
53+
oldSchedulerKey = "scheduling-policy.nri.io"
5054
)
5155

5256
var (
@@ -79,6 +83,17 @@ type ioPrio struct {
7983
Priority int32 `json:"priority"`
8084
}
8185

86+
// scheduler attribute adjustment
87+
type scheduler struct {
88+
Policy string `json:"policy"`
89+
Nice int32 `json:"nice"`
90+
Priority int32 `json:"priority"`
91+
Flags []string `json:"flags"`
92+
Runtime uint64 `json:"runtime"`
93+
Deadline uint64 `json:"deadline"`
94+
Period uint64 `json:"period"`
95+
}
96+
8297
// our injector plugin
8398
type plugin struct {
8499
stub stub.Stub
@@ -107,6 +122,9 @@ func (p *plugin) CreateContainer(_ context.Context, pod *api.PodSandbox, ctr *ap
107122
if err := setIOPriority(pod, ctr, adjust); err != nil {
108123
return nil, nil, err
109124
}
125+
if err := adjustScheduler(pod, ctr, adjust); err != nil {
126+
return nil, nil, err
127+
}
110128

111129
if verbose {
112130
dump(containerName(pod, ctr), "ContainerAdjustment", adjust)
@@ -269,6 +287,29 @@ func setIOPriority(pod *api.PodSandbox, ctr *api.Container, a *api.ContainerAdju
269287
return nil
270288
}
271289

290+
func adjustScheduler(pod *api.PodSandbox, ctr *api.Container, a *api.ContainerAdjustment) error {
291+
sch, err := parseScheduler(ctr.Name, pod.Annotations)
292+
if err != nil {
293+
return err
294+
}
295+
296+
if sch == nil {
297+
log.Debugf("%s: no scheduling attributes annotated...", containerName(pod, ctr))
298+
return nil
299+
}
300+
301+
if verbose {
302+
dump(containerName(pod, ctr), "annotated scheduling attributes", sch)
303+
}
304+
305+
a.SetLinuxScheduler(sch.ToNRI())
306+
if !verbose {
307+
log.Infof("%s: adjusted scheduling attributes to %s...", containerName(pod, ctr), sch)
308+
}
309+
310+
return nil
311+
}
312+
272313
func parseIOPriority(ctr string, annotations map[string]string) (*ioPrio, error) {
273314
var (
274315
priority = &ioPrio{}
@@ -286,6 +327,23 @@ func parseIOPriority(ctr string, annotations map[string]string) (*ioPrio, error)
286327
return priority, nil
287328
}
288329

330+
func parseScheduler(ctr string, annotations map[string]string) (*scheduler, error) {
331+
var (
332+
sch = &scheduler{}
333+
)
334+
335+
annotation := getAnnotation(annotations, schedulerKey, oldSchedulerKey, ctr)
336+
if annotation == nil {
337+
return nil, nil
338+
}
339+
340+
if err := yaml.Unmarshal(annotation, sch); err != nil {
341+
return nil, fmt.Errorf("invalid scheduler annotation %q: %w", string(annotation), err)
342+
}
343+
344+
return sch, nil
345+
}
346+
289347
func getAnnotation(annotations map[string]string, mainKey, oldKey, ctr string) []byte {
290348
for _, key := range []string{
291349
mainKey + "/container." + ctr,
@@ -369,6 +427,47 @@ func (p *ioPrio) String() string {
369427
return fmt.Sprintf("<I/O priority class %s:%d>", p.Class, p.Priority)
370428
}
371429

430+
// Convert scheduling attributes to the NRI API representation.
431+
func (sch *scheduler) ToNRI() *api.LinuxScheduler {
432+
apiSch := &api.LinuxScheduler{
433+
Policy: api.LinuxSchedulerPolicy(api.LinuxSchedulerPolicy_value[sch.Policy]),
434+
Nice: sch.Nice,
435+
Priority: sch.Priority,
436+
Runtime: sch.Runtime,
437+
Deadline: sch.Deadline,
438+
Period: sch.Period,
439+
}
440+
441+
for _, f := range sch.Flags {
442+
apiSch.Flags = append(apiSch.Flags, api.LinuxSchedulerFlag(api.LinuxSchedulerFlag_value[f]))
443+
}
444+
445+
return apiSch
446+
}
447+
448+
func (sc *scheduler) String() string {
449+
if sc == nil {
450+
return "<no scheduling attributes>"
451+
}
452+
453+
s := fmt.Sprintf("<scheduler policy=%s", sc.Policy)
454+
if sc.Nice != 0 {
455+
s += fmt.Sprintf(", nice=%d", sc.Nice)
456+
}
457+
if sc.Priority != 0 {
458+
s += fmt.Sprintf(", priority=%d", sc.Priority)
459+
}
460+
if sc.Runtime != 0 {
461+
s += fmt.Sprintf(", runtime=%d, deadline=%d, period=%d", sc.Runtime, sc.Deadline, sc.Period)
462+
}
463+
if len(sc.Flags) > 0 {
464+
s += fmt.Sprintf(", flags=%v", sc.Flags)
465+
}
466+
s += ">"
467+
468+
return s
469+
}
470+
372471
// Construct a container name for log messages.
373472
func containerName(pod *api.PodSandbox, container *api.Container) string {
374473
if pod != nil {

0 commit comments

Comments
 (0)