Fix sff panic deadlock, share the evdev probe, assorted review cleanups
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user