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
+19 -7
View File
@@ -15,10 +15,15 @@ type sff struct {
// Every transport touch happens on the loop goroutine: requests execute
// one at a time, each admitted by the module type's own gate first.
reqs chan func()
reqs chan sffReq
admit func()
}
type sffReq struct {
fn func()
done chan struct{}
}
func openSFF(ifname string) (*sff, error) {
devLink, err := os.Readlink("/sys/class/net/" + ifname + "/device")
if err != nil {
@@ -34,7 +39,7 @@ func openSFF(ifname string) (*sff, error) {
s := &sff{
ifname: ifname,
path: "/sys/kernel/debug/ixgbe/" + filepath.Base(devLink) + "/sff_i2c",
reqs: make(chan func()),
reqs: make(chan sffReq),
admit: func() {},
}
if _, err := os.Stat(s.path); err != nil {
@@ -45,16 +50,23 @@ func openSFF(ifname string) (*sff, error) {
}
func (s *sff) loop() {
defer holdPanic()
for fn := range s.reqs {
s.admit()
fn()
for r := range s.reqs {
s.serve(r)
}
}
// done closes even when the request panics, and the recover keeps the loop
// serving, so no exec caller is ever stranded waiting on a dead loop.
func (s *sff) serve(r sffReq) {
defer close(r.done)
defer holdPanic()
s.admit()
r.fn()
}
func (s *sff) exec(fn func()) {
done := make(chan struct{})
s.reqs <- func() { fn(); close(done) }
s.reqs <- sffReq{fn: fn, done: done}
<-done
}