summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorBhasker Hariharan <bhaskerh@google.com>2020-03-19 09:59:21 -0700
committergVisor bot <gvisor-bot@google.com>2020-03-19 10:00:31 -0700
commit3a37f6791745a26d38b69fbe9d4090f8fd0c7827 (patch)
tree5e66715e77a83b4df14faa01ce01588a820e9254
parentfd27a917ef068a4e17cddbe3f671b59f52e6e030 (diff)
Change SocketOperations.readMu to an RWMutex.
Also get rid of the readViewHasData as it's not required anymore. Updates #231, #357 PiperOrigin-RevId: 301837227
-rw-r--r--pkg/sentry/socket/netstack/netstack.go22
1 files changed, 4 insertions, 18 deletions
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