Fix sff panic deadlock, share the evdev probe, assorted review cleanups

This commit is contained in:
flamingcow
2026-08-31 15:51:52 -07:00
parent 10d97ee82a
commit e4731c94cd
13 changed files with 205 additions and 272 deletions
+15 -54
View File
@@ -100,7 +100,7 @@ func allRuleLocations(fd int, ifname string) ([]uint32, uint32, error) {
// rule_locs follows rule_cnt directly, before the struct's tail padding,
// and that is where the kernel copies it to.
locOff := unsafe.Offsetof(ethtoolRxnfc{}.ruleCnt) + 4
buf := make([]byte, int(unsafe.Sizeof(ethtoolRxnfc{}))+4*int(cnt.ruleCnt))
buf := statsBuf((int(unsafe.Sizeof(ethtoolRxnfc{})) + 4*int(cnt.ruleCnt) + 7) / 8)
all := (*ethtoolRxnfc)(unsafe.Pointer(&buf[0]))
all.cmd = ethtoolGRXCLSRLALL
all.ruleCnt = cnt.ruleCnt
@@ -113,7 +113,7 @@ func allRuleLocations(fd int, ifname string) ([]uint32, uint32, error) {
ifname, all.ruleCnt, cnt.ruleCnt)
}
raw := buf[locOff:]
raw := unsafe.Slice((*byte)(unsafe.Pointer(&buf[0])), len(buf)*8)[locOff:]
locs := make([]uint32, 0, all.ruleCnt)
for i := 0; i < int(all.ruleCnt); i++ {
locs = append(locs, binary.LittleEndian.Uint32(raw[i*4:]))
@@ -311,7 +311,10 @@ type ethtoolCoalesce struct {
}
const (
wantGovernor = "performance"
wantGovernor = "performance"
// Under the performance governor a max-frequency bound is a fixed clock, not a
// ceiling the cores rove beneath, so the line-rate margin it was qualified with
// is the margin every run gets.
wantMaxFreqKHz = "2000000"
wantCoalesceUsecs = 25
wantRxRing = 8160
@@ -522,11 +525,11 @@ func (r *statReader) sum() uint64 {
return total
}
func checkGovernor(want string) checkResult {
res := checkResult{item: "cpu governor"}
paths, err := filepath.Glob("/sys/devices/system/cpu/cpu*/cpufreq/scaling_governor")
func checkCPUAttr(item, attr, want, unit string) checkResult {
res := checkResult{item: item}
paths, err := filepath.Glob("/sys/devices/system/cpu/cpu*/cpufreq/" + attr)
if err != nil || len(paths) == 0 {
res.err = fmt.Errorf("no cpufreq governors found")
res.err = fmt.Errorf("no cpufreq %s found", attr)
return res
}
var wrong []string
@@ -544,7 +547,7 @@ func checkGovernor(want string) checkResult {
}
}
if len(wrong) == 0 {
res.state = fmt.Sprintf("%s on all %d cpus", want, len(paths))
res.state = fmt.Sprintf("%s%s on all %d cpus", want, unit, len(paths))
return res
}
var found []string
@@ -559,51 +562,7 @@ func checkGovernor(want string) checkResult {
}
}
res.fixed = true
res.state = fmt.Sprintf("was %s, now %s on all %d cpus", strings.Join(found, " "), want, len(paths))
return res
}
// Under the performance governor a max-frequency bound is a fixed clock, not a
// ceiling the cores rove beneath, so the line-rate margin it was qualified with
// is the margin every run gets.
func checkMaxFreq(wantKHz string) checkResult {
res := checkResult{item: "cpu max frequency"}
paths, err := filepath.Glob("/sys/devices/system/cpu/cpu*/cpufreq/scaling_max_freq")
if err != nil || len(paths) == 0 {
res.err = fmt.Errorf("no cpufreq max frequencies found")
return res
}
var wrong []string
counts := map[string]int{}
for _, p := range paths {
b, err := os.ReadFile(p)
if err != nil {
res.err = err
return res
}
got := strings.TrimSpace(string(b))
counts[got]++
if got != wantKHz {
wrong = append(wrong, p)
}
}
if len(wrong) == 0 {
res.state = fmt.Sprintf("%s kHz on all %d cpus", wantKHz, len(paths))
return res
}
var found []string
for k, v := range counts {
found = append(found, fmt.Sprintf("%s:%d", k, v))
}
for _, p := range wrong {
if err := os.WriteFile(p, []byte(wantKHz), 0o644); err != nil {
res.err = err
res.state = fmt.Sprintf("could not set %s", p)
return res
}
}
res.fixed = true
res.state = fmt.Sprintf("was %s, now %s kHz on all %d cpus", strings.Join(found, " "), wantKHz, len(paths))
res.state = fmt.Sprintf("was %s, now %s%s on all %d cpus", strings.Join(found, " "), want, unit, len(paths))
return res
}
@@ -774,7 +733,9 @@ func withIoctlSocket(fn func(fd int) []checkResult) []checkResult {
// under test, so with no cable there is never going to be one.
func configureSystem(ifnames []string, ethertypes []uint16) []checkResult {
return withIoctlSocket(func(fd int) []checkResult {
out := []checkResult{checkGovernor(wantGovernor), checkMaxFreq(wantMaxFreqKHz),
out := []checkResult{
checkCPUAttr("cpu governor", "scaling_governor", wantGovernor, ""),
checkCPUAttr("cpu max frequency", "scaling_max_freq", wantMaxFreqKHz, " kHz"),
checkIdleLatency(wantIdleLatency)}
for i, ifname := range ifnames {
out = append(out, checkLinkUp(fd, ifname))