summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGhanan Gowripalan <ghanan@google.com>2021-11-02 14:51:10 -0700
committergVisor bot <gvisor-bot@google.com>2021-11-02 14:53:39 -0700
commit88cf2e93e5ca3ce0f852a0e3dfb06099777c08c0 (patch)
tree847001294e566037ad08e5618970160e95130d2d
parent3141bf7a245795969685e7f7f4ef09a0dcde19f8 (diff)
Extract tcb & lastUsed to its own lock
These fields do not need to synchronize reads/writes with the rest of the connection. PiperOrigin-RevId: 407183693
-rw-r--r--pkg/tcpip/stack/conntrack.go29
1 files changed, 17 insertions, 12 deletions
diff --git a/pkg/tcpip/stack/conntrack.go b/pkg/tcpip/stack/conntrack.go
index c51d5c09a..1c6060b70 100644
--- a/pkg/tcpip/stack/conntrack.go
+++ b/pkg/tcpip/stack/conntrack.go
@@ -119,22 +119,24 @@ type conn struct {
//
// +checklocks:mu
destinationManip bool
+
+ stateMu sync.RWMutex `state:"nosave"`
// tcb is TCB control block. It is used to keep track of states
// of tcp connection.
//
- // +checklocks:mu
+ // +checklocks:stateMu
tcb tcpconntrack.TCB
// lastUsed is the last time the connection saw a relevant packet, and
// is updated by each packet on the connection.
//
- // +checklocks:mu
+ // +checklocks:stateMu
lastUsed tcpip.MonotonicTime
}
// timedOut returns whether the connection timed out based on its state.
func (cn *conn) timedOut(now tcpip.MonotonicTime) bool {
- cn.mu.RLock()
- defer cn.mu.RUnlock()
+ cn.stateMu.RLock()
+ defer cn.stateMu.RUnlock()
if cn.tcb.State() == tcpconntrack.ResultAlive {
// Use the same default as Linux, which doesn't delete
// established connections for 5(!) days.
@@ -147,7 +149,7 @@ func (cn *conn) timedOut(now tcpip.MonotonicTime) bool {
// update the connection tracking state.
//
-// +checklocks:cn.mu
+// +checklocks:cn.stateMu
func (cn *conn) updateLocked(pkt *PacketBuffer, reply bool) {
if pkt.TransportProtocolNumber != header.TCPProtocolNumber {
return
@@ -607,14 +609,17 @@ func (cn *conn) handlePacket(pkt *PacketBuffer, hook Hook, rt *Route) bool {
// packets are fragmented.
reply := pkt.tuple.reply
- tid, performManip := func() (tupleID, bool) {
- cn.mu.Lock()
- defer cn.mu.Unlock()
- // Mark the connection as having been used recently so it isn't reaped.
- cn.lastUsed = cn.ct.clock.NowMonotonic()
- // Update connection state.
- cn.updateLocked(pkt, reply)
+ cn.stateMu.Lock()
+ // Mark the connection as having been used recently so it isn't reaped.
+ cn.lastUsed = cn.ct.clock.NowMonotonic()
+ // Update connection state.
+ cn.updateLocked(pkt, reply)
+ cn.stateMu.Unlock()
+
+ tid, performManip := func() (tupleID, bool) {
+ cn.mu.RLock()
+ defer cn.mu.RUnlock()
var tuple *tuple
if reply {