diff --git a/pkg/tcpip/transport/tcp/segment_queue.go b/pkg/tcpip/transport/tcp/segment_queue.go index 568c7d358..53839387e 100644 --- a/pkg/tcpip/transport/tcp/segment_queue.go +++ b/pkg/tcpip/transport/tcp/segment_queue.go @@ -37,10 +37,8 @@ func (q *segmentQueue) emptyLocked() bool { // empty determines if the queue is empty. func (q *segmentQueue) empty() bool { q.mu.Lock() - r := q.emptyLocked() - q.mu.Unlock() - - return r + defer q.mu.Unlock() + return q.emptyLocked() } // enqueue adds the given segment to the queue. @@ -54,7 +52,10 @@ func (q *segmentQueue) enqueue(s *segment) bool { // avoid lock order inversion. bufSz := q.ep.ops.GetReceiveBufferSize() used := q.ep.receiveMemUsed() + q.mu.Lock() + defer q.mu.Unlock() + // Allow zero sized segments (ACK/FIN/RSTs etc even if the segment queue // is currently full). allow := (used <= int(bufSz) || s.payloadSize() == 0) && !q.frozen @@ -65,7 +66,6 @@ func (q *segmentQueue) enqueue(s *segment) bool { // Set the owner now that the endpoint owns the segment. s.setOwner(q.ep, recvQ) } - q.mu.Unlock() return allow } @@ -75,11 +75,12 @@ func (q *segmentQueue) enqueue(s *segment) bool { // the ref count when done. func (q *segmentQueue) dequeue() *segment { q.mu.Lock() + defer q.mu.Unlock() + s := q.list.Front() if s != nil { q.list.Remove(s) } - q.mu.Unlock() return s } @@ -89,14 +90,14 @@ func (q *segmentQueue) dequeue() *segment { // queue till the queue is unfroze with a corresponding segmentQueue.thaw call. func (q *segmentQueue) freeze() { q.mu.Lock() + defer q.mu.Unlock() q.frozen = true - q.mu.Unlock() } // thaw unfreezes a previously frozen queue using segmentQueue.freeze() and // allows new segments to be queued again. func (q *segmentQueue) thaw() { q.mu.Lock() + defer q.mu.Unlock() q.frozen = false - q.mu.Unlock() }