Cap cpu idle exit latency for the life of the run, deep enough to keep C1 and shallow enough to block the rest
This commit is contained in:
@@ -257,6 +257,7 @@ const (
|
|||||||
wantCoalesceUsecs = 25
|
wantCoalesceUsecs = 25
|
||||||
wantRxRing = 8160
|
wantRxRing = 8160
|
||||||
wantTxRing = 4096
|
wantTxRing = 4096
|
||||||
|
wantIdleLatency = 10
|
||||||
)
|
)
|
||||||
|
|
||||||
type checkResult struct {
|
type checkResult struct {
|
||||||
@@ -502,6 +503,31 @@ func checkGovernor(want string) checkResult {
|
|||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Bounds how far into idle any cpu may sink, so a worker or interrupt never
|
||||||
|
// waits behind a deep state's exit. Ten microseconds admits C1, whose exit is
|
||||||
|
// noise under the interrupt coalescing already in the path, and blocks the
|
||||||
|
// states whose exits are many times that window. The kernel honours the bound
|
||||||
|
// for exactly as long as the fd stays open, which is why it is opened once and
|
||||||
|
// deliberately never closed: as PID 1 its lifetime is the machine's, and
|
||||||
|
// everything is restored the moment the process goes.
|
||||||
|
func checkIdleLatency(usecs uint32) checkResult {
|
||||||
|
res := checkResult{item: "cpu idle latency"}
|
||||||
|
fd, err := unix.Open("/dev/cpu_dma_latency", unix.O_RDWR|unix.O_CLOEXEC, 0)
|
||||||
|
if err != nil {
|
||||||
|
res.err = fmt.Errorf("opening /dev/cpu_dma_latency: %w", err)
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
var buf [4]byte
|
||||||
|
binary.NativeEndian.PutUint32(buf[:], usecs)
|
||||||
|
if _, err := unix.Write(fd, buf[:]); err != nil {
|
||||||
|
unix.Close(fd)
|
||||||
|
res.err = fmt.Errorf("writing cpu latency bound: %w", err)
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
res.state = fmt.Sprintf("capped at %dus while running", usecs)
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
func checkLinkUp(fd int, ifname string) checkResult {
|
func checkLinkUp(fd int, ifname string) checkResult {
|
||||||
res := checkResult{item: ifname + " link up"}
|
res := checkResult{item: ifname + " link up"}
|
||||||
var ifr flagsIfreq
|
var ifr flagsIfreq
|
||||||
@@ -601,7 +627,7 @@ func withIoctlSocket(fn func(fd int) []checkResult) []checkResult {
|
|||||||
// under test, so with no cable there is never going to be one.
|
// under test, so with no cable there is never going to be one.
|
||||||
func configureSystem(ifnames []string, ethertypes []uint16) []checkResult {
|
func configureSystem(ifnames []string, ethertypes []uint16) []checkResult {
|
||||||
return withIoctlSocket(func(fd int) []checkResult {
|
return withIoctlSocket(func(fd int) []checkResult {
|
||||||
out := []checkResult{checkGovernor(wantGovernor)}
|
out := []checkResult{checkGovernor(wantGovernor), checkIdleLatency(wantIdleLatency)}
|
||||||
for _, ifname := range ifnames {
|
for _, ifname := range ifnames {
|
||||||
out = append(out, checkLinkUp(fd, ifname))
|
out = append(out, checkLinkUp(fd, ifname))
|
||||||
out = append(out, clearFlowRules(fd, ifname))
|
out = append(out, clearFlowRules(fd, ifname))
|
||||||
|
|||||||
Reference in New Issue
Block a user