diff --git a/pkg/sentry/kernel/epoll/epoll.go b/pkg/sentry/kernel/epoll/epoll.go index fca9f7a91..e56f422c8 100644 --- a/pkg/sentry/kernel/epoll/epoll.go +++ b/pkg/sentry/kernel/epoll/epoll.go @@ -212,6 +212,7 @@ func (e *EventPoll) eventsAvailable() bool { return false } defer func() { + notify := true e.listsMu.Lock() e.readyList.PushFrontList(&readyList) var next *pollEntry @@ -221,12 +222,16 @@ func (e *EventPoll) eventsAvailable() bool { // entry.NotifyEvent() was called while we were running. waitingList.Remove(entry) e.readyList.PushBack(entry) + notify = true } else { entry.curList = &e.waitingList } } e.waitingList.PushBackList(&waitingList) e.listsMu.Unlock() + if notify { + e.Notify(waiter.ReadableEvents) + } }() for it := readyList.Front(); it != nil; { @@ -287,6 +292,7 @@ func (e *EventPoll) ReadEvents(max int) []linux.EpollEvent { return nil } defer func() { + notify := false e.listsMu.Lock() e.readyList.PushFrontList(&readyList) var next *pollEntry @@ -296,6 +302,7 @@ func (e *EventPoll) ReadEvents(max int) []linux.EpollEvent { // entry.NotifyEvent() was called while we were running. waitingList.Remove(entry) e.readyList.PushBack(entry) + notify = true } else { entry.curList = &e.waitingList } @@ -307,6 +314,9 @@ func (e *EventPoll) ReadEvents(max int) []linux.EpollEvent { } e.disabledList.PushBackList(&disabledList) e.listsMu.Unlock() + if notify { + e.Notify(waiter.ReadableEvents) + } }() // Go through all entries we believe may be ready. diff --git a/pkg/sentry/vfs/epoll.go b/pkg/sentry/vfs/epoll.go index 6041f8ff6..dd885e579 100644 --- a/pkg/sentry/vfs/epoll.go +++ b/pkg/sentry/vfs/epoll.go @@ -170,6 +170,7 @@ func (ep *EpollInstance) Readiness(mask waiter.EventMask) waiter.EventMask { return 0 } defer func() { + notify := false ep.readyMu.Lock() ep.ready.PushFrontList(&ready) var next *epollInterest @@ -179,11 +180,15 @@ func (ep *EpollInstance) Readiness(mask waiter.EventMask) waiter.EventMask { // epi.NotifyEvent() was called while we were running. notReady.Remove(epi) ep.ready.PushBack(epi) + notify = true } else { epi.ready = false } } ep.readyMu.Unlock() + if notify { + ep.q.Notify(waiter.ReadableEvents) + } }() var next *epollInterest @@ -428,6 +433,7 @@ func (ep *EpollInstance) ReadEvents(events []linux.EpollEvent, maxEvents int) [] return nil } defer func() { + notify := false ep.readyMu.Lock() // epollInterests that we never checked are re-inserted at the start of // ep.ready. epollInterests that were ready are re-inserted at the end @@ -440,12 +446,16 @@ func (ep *EpollInstance) ReadEvents(events []linux.EpollEvent, maxEvents int) [] // epi.NotifyEvent() was called while we were running. notReady.Remove(epi) ep.ready.PushBack(epi) + notify = true } else { epi.ready = false } } ep.ready.PushBackList(&requeue) ep.readyMu.Unlock() + if notify { + ep.q.Notify(waiter.ReadableEvents) + } }() i := 0