Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Linux kernel ticks assumption is error prone #122

Open
uri-weisman opened this issue Jul 7, 2022 · 3 comments
Open

Linux kernel ticks assumption is error prone #122

uri-weisman opened this issue Jul 7, 2022 · 3 comments
Labels
enhancement New feature or request

Comments

@uri-weisman
Copy link

Problem

The value of clock ticks (_SC_CLK_TCK) is hard coded and might varies across kernel versions and hardware platforms, it would probably be best if you could read this value dynamically.

There is an assumption here for certain conditions that might not be respected between different deployments and versions.
please read the wiki article about Kernel Timer Systems:

The original kernel timer system (called the "timer wheel) was based on incrementing a kernel-internal value (jiffies) every timer interrupt. The timer interrupt becomes the default scheduling quantum, and all other timers are based on jiffies. The timer interrupt rate (and jiffy increment rate) is defined by a compile-time constant called HZ. Different platforms use different values for HZ. Historically, the kernel used 100 as the value for HZ, yielding a jiffy interval of 10 ms. With 2.4, the HZ value for i386 was changed to 1000, yielding a jiffy interval of 1 ms. Recently (2.6.13) the kernel changed HZ for i386 to 250. (1000 was deemed too high).

Proposed solution

Make a sys call to retrieve the actual _SC_CLK_TCK and use it for process time calculations, the same has been done for Darwin:

// getClockTicks returns the number of click ticks in one jiffie.
func getClockTicks() int {
return int(C.sysconf(C._SC_CLK_TCK))
}

@andrewkroh
Copy link
Member

IIUC, looking at 2.6.23 (the earliest kernel supported by Go) the two architectures that do not use 100 HZ are alpha and ia64. And neither of those are supported by Go.

But I agree it would be more correct to use the sysconf(_SC_CLK_TCK). Currently cgo is not required for the Linux provider implementation. I think it would be good to keep it that way and offer two implementations. One that uses the constant (ticks_nocgo.go) and one that uses code similar to the proposal above (ticks_cgo.go).

There's some good discussion of this in containerd/cgroups#12.

@andrewkroh
Copy link
Member

andrewkroh commented Jul 7, 2022

I was curious what go-sysconf did for this since it claims to not use cgo.

https://github.com/tklauser/go-sysconf/blob/0dc6a3a166617b00a369c95264f8ee435c0a4910/sysconf_linux.go#L19-L26

const (
	// CLK_TCK is a constant on Linux for all architectures except alpha and ia64.
	// See e.g.
	// https://git.musl-libc.org/cgit/musl/tree/src/conf/sysconf.c#n30
	// https://github.com/containerd/cgroups/pull/12
	// https://lore.kernel.org/lkml/[email protected]/
	_SYSTEM_CLK_TCK = 100
)

@uri-weisman
Copy link
Author

@andrewkroh - thank you for the quick response.

IIUC, looking at 2.6.23 (the earliest kernel supported by Go) the two architectures that do not use 100 HZ are alpha and ia64. And neither of those are supported by Go.

Seems they are both obsolete so it makes this issue less important.
Yeah, two different implementations sound about right - allowing the user to decide if he wants to support cgo.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants