Skip to content

Support process.scheduler#3962

Closed
utam0k wants to merge 1 commit intoopencontainers:mainfrom
utam0k:scheduler
Closed

Support process.scheduler#3962
utam0k wants to merge 1 commit intoopencontainers:mainfrom
utam0k:scheduler

Conversation

@utam0k
Copy link
Copy Markdown
Member

@utam0k utam0k commented Aug 4, 2023

Spec: opencontainers/runtime-spec#1188
Fix: opencontainers#3895

Signed-off-by: utam0k <k0ma@utam0k.jp>
SchedDeadline: scheduler.Deadline,
SchedPeriod: scheduler.Period,
}
_, _, errno := syscall.Syscall(C.SYS_sched_setattr, uintptr(pid), uintptr(unsafe.Pointer(attr)), uintptr(0))
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
_, _, errno := syscall.Syscall(C.SYS_sched_setattr, uintptr(pid), uintptr(unsafe.Pointer(attr)), uintptr(0))
_, _, errno := syscall.Syscall(unix.SYS_SCHED_SETATTR, uintptr(pid), uintptr(unsafe.Pointer(attr)), uintptr(0))

[ "$status" -eq 0 ]
[[ "${lines[0]}" == *"scheduling policy: SCHED_DEADLINE"* ]]
[[ "${lines[1]}" == *"priority: 0"* ]]
[[ "${lines[2]}" == *"runtime/deadline/period parameters: 42000/1000000/1000000"* ]]
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

* should be avoided for comparing numbers

Suggested change
[[ "${lines[2]}" == *"runtime/deadline/period parameters: 42000/1000000/1000000"* ]]
[[ "${lines[2]}" == "runtime/deadline/period parameters: 42000/1000000/1000000" ]]

return os.NewFile(uintptr(fds[1]), name+"-p"), os.NewFile(uintptr(fds[0]), name+"-c"), nil
}

type schedAttr struct {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would want to be very sure that the padding is handled here exactly the same as with C. Can we make this a CGo structure? Or does Go have padding guarantees that match C?

// SetSchedAttr sets the scheduler attributes for the process with the given pid.
// Please refer to the following link for kernel-specific values:
// https://github.com/torvalds/linux/blob/c1a515d3c0270628df8ae5f5118ba859b85464a2/include/uapi/linux/sched.h#L111-L134
func SetSchedAttr(pid int, scheduler *configs.Scheduler) error {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason golang.org/x/sys/unix doesn't have a wrapper for this? This syscall is fairly old -- first added in Linux 3.14.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My best guess is "no one bothered to". Let me give it a try.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's my attempt https://go-review.googlesource.com/c/sys/+/516756

(my best guess is "because of this ugly linux/glibc header conflict" now)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@utam0k the above PR is now merged; can you please vendor latest (@Head) x/sys/unix and use unix.SetSchedAttr?

Alas, this PR will have to be marked as draft until x/sys/unix makes a release.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#4006 comes with SchedSetAttr

}
_, _, errno := syscall.Syscall(C.SYS_sched_setattr, uintptr(pid), uintptr(unsafe.Pointer(attr)), uintptr(0))
if errno != 0 {
return errno
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should wrap an new error to indicate what's the error's exact means.
There is a case, if cpus in config.json doesn't include all CPUs in the system, sched_setattr(2) will fail with EPERM, but the error msg of runc is:

ERRO[0000] runc run failed: unable to start container process: error during container init: error setting scheduler: operation not permitted

Most of us may not know what happened.

Please refer: https://man7.org/linux/man-pages/man2/sched_setattr.2.html,

return (st1.Dev == st2.Dev) && (st1.Ino == st2.Ino), nil
}

func scheduler(config *configs.Config) error {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shall we need to check the conflict with CPUs?

EPERM  The CPU affinity mask of the thread specified by pid does
              not include all CPUs in the system

@lifubang
Copy link
Copy Markdown
Member

ping @utam0k Could you please rebase and resolve the conflicting files?

Comment on lines +224 to +232
// Scheduler is based on the Linux sched_setattr(2) syscall.
type Scheduler struct {
Policy specs.LinuxSchedulerPolicy `json:"policy"`
Nice int32 `json:"nice,omitempty"`
Priority int32 `json:"priority,omitempty"`
Flags []specs.LinuxSchedulerFlag `json:"flags,omitempty"`
Runtime uint64 `json:"runtime,omitempty"`
Deadline uint64 `json:"deadline,omitempty"`
Period uint64 `json:"period,omitempty"`
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, can we maybe do type Scheduler = specs.Scheduler here?

NoMountFallback bool `json:"no_mount_fallback,omitempty"`

// Scheduler represents the scheduling attributes for a process.
Scheduler *Scheduler `json:"shceduler,omitempty"`
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo in json attribute name

Comment on lines +496 to +506
if spec.Process.Scheduler != nil {
config.Scheduler = &configs.Scheduler{
Policy: spec.Process.Scheduler.Policy,
Nice: spec.Process.Scheduler.Nice,
Priority: spec.Process.Scheduler.Priority,
Flags: spec.Process.Scheduler.Flags,
Runtime: spec.Process.Scheduler.Runtime,
Deadline: spec.Process.Scheduler.Deadline,
Period: spec.Process.Scheduler.Period,
}
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since spec.Process.Scheduler is of the same type as config.Scheduler, you can just assign it directly, no need to go field-by-field.

@lifubang
Copy link
Copy Markdown
Member

Needs rebase.
@utam0k Do you still work on this PR? If not, I can handle this one to push it forward.

@utam0k
Copy link
Copy Markdown
Member Author

utam0k commented Sep 24, 2023

@lifubang I have been away from this PR. If you are interested, please do 🙏

@lifubang
Copy link
Copy Markdown
Member

@lifubang I have been away from this PR. If you are interested, please do 🙏

#4025

@utam0k
Copy link
Copy Markdown
Member Author

utam0k commented Sep 25, 2023

#4025

@utam0k utam0k closed this Sep 25, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support process.scheduler

5 participants