From 3a37f6791745a26d38b69fbe9d4090f8fd0c7827 Mon Sep 17 00:00:00 2001 From: Bhasker Hariharan Date: Thu, 19 Mar 2020 09:59:21 -0700 Subject: Change SocketOperations.readMu to an RWMutex. Also get rid of the readViewHasData as it's not required anymore. Updates #231, #357 PiperOrigin-RevId: 301837227 --- pkg/sentry/socket/netstack/netstack.go | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-) (limited to 'pkg/sentry/socket/netstack/netstack.go') diff --git a/pkg/sentry/socket/netstack/netstack.go b/pkg/sentry/socket/netstack/netstack.go index a2e1da02f..a6ef7a47e 100644 --- a/pkg/sentry/socket/netstack/netstack.go +++ b/pkg/sentry/socket/netstack/netstack.go @@ -29,7 +29,6 @@ import ( "io" "math" "reflect" - "sync/atomic" "syscall" "time" @@ -265,14 +264,8 @@ type SocketOperations struct { skType linux.SockType protocol int - // readViewHasData is 1 iff readView has data to be read, 0 otherwise. - // Must be accessed using atomic operations. It must only be written - // with readMu held but can be read without holding readMu. The latter - // is required to avoid deadlocks in epoll Readiness checks. - readViewHasData uint32 - // readMu protects access to the below fields. - readMu sync.Mutex `state:"nosave"` + readMu sync.RWMutex `state:"nosave"` // readView contains the remaining payload from the last packet. readView buffer.View // readCM holds control message information for the last packet read @@ -428,13 +421,11 @@ func (s *SocketOperations) fetchReadView() *syserr.Error { v, cms, err := s.Endpoint.Read(&s.sender) if err != nil { - atomic.StoreUint32(&s.readViewHasData, 0) return syserr.TranslateNetstackError(err) } s.readView = v s.readCM = cms - atomic.StoreUint32(&s.readViewHasData, 1) return nil } @@ -633,9 +624,11 @@ func (s *SocketOperations) Readiness(mask waiter.EventMask) waiter.EventMask { // Check our cached value iff the caller asked for readability and the // endpoint itself is currently not readable. if (mask & ^r & waiter.EventIn) != 0 { - if atomic.LoadUint32(&s.readViewHasData) == 1 { + s.readMu.RLock() + if len(s.readView) > 0 { r |= waiter.EventIn } + s.readMu.RUnlock() } return r @@ -2342,9 +2335,6 @@ func (s *SocketOperations) coalescingRead(ctx context.Context, dst usermem.IOSeq } copied += n s.readView.TrimFront(n) - if len(s.readView) == 0 { - atomic.StoreUint32(&s.readViewHasData, 0) - } dst = dst.DropFirst(n) if e != nil { @@ -2468,10 +2458,6 @@ func (s *SocketOperations) nonBlockingRead(ctx context.Context, dst usermem.IOSe s.readView.TrimFront(int(n)) } - if len(s.readView) == 0 { - atomic.StoreUint32(&s.readViewHasData, 0) - } - var flags int if msgLen > int(n) { flags |= linux.MSG_TRUNC -- cgit v1.2.3