Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

rxrpc: Cache the congestion window setting

Cache the congestion window setting that was determined during a call's
transmission phase when it finishes so that it can be used by the next call
to the same peer, thereby shortcutting the slow-start algorithm.

The value is stored in the rxrpc_peer struct and is accessed without
locking. Each call takes the value that happens to be there when it starts
and just overwrites the value when it finishes.

Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

David Howells and committed by
David S. Miller
f7aec129 0430a260

+19 -6
+2
net/rxrpc/ar-internal.h
··· 300 300 u64 rtt_cache[RXRPC_RTT_CACHE_SIZE]; /* Determined RTT cache */ 301 301 u8 rtt_cursor; /* next entry at which to insert */ 302 302 u8 rtt_usage; /* amount of cache actually used */ 303 + 304 + u8 cong_cwnd; /* Congestion window size */ 303 305 }; 304 306 305 307 /*
+1
net/rxrpc/call_accept.c
··· 310 310 rxrpc_see_call(call); 311 311 call->conn = conn; 312 312 call->peer = rxrpc_get_peer(conn->params.peer); 313 + call->cong_cwnd = call->peer->cong_cwnd; 313 314 return call; 314 315 } 315 316
+1 -6
net/rxrpc/call_object.c
··· 136 136 call->tx_winsize = 16; 137 137 call->rx_expect_next = 1; 138 138 139 - if (RXRPC_TX_SMSS > 2190) 140 - call->cong_cwnd = 2; 141 - else if (RXRPC_TX_SMSS > 1095) 142 - call->cong_cwnd = 3; 143 - else 144 - call->cong_cwnd = 4; 139 + call->cong_cwnd = 2; 145 140 call->cong_ssthresh = RXRPC_RXTX_BUFF_SIZE - 1; 146 141 return call; 147 142
+6
net/rxrpc/conn_client.c
··· 292 292 if (!cp->peer) 293 293 goto error; 294 294 295 + call->cong_cwnd = cp->peer->cong_cwnd; 296 + if (call->cong_cwnd >= call->cong_ssthresh) 297 + call->cong_mode = RXRPC_CALL_CONGEST_AVOIDANCE; 298 + else 299 + call->cong_mode = RXRPC_CALL_SLOW_START; 300 + 295 301 /* If the connection is not meant to be exclusive, search the available 296 302 * connections to see if the connection we want to use already exists. 297 303 */
+2
net/rxrpc/conn_object.c
··· 193 193 { 194 194 struct rxrpc_connection *conn = call->conn; 195 195 196 + call->peer->cong_cwnd = call->cong_cwnd; 197 + 196 198 spin_lock_bh(&conn->params.peer->lock); 197 199 hlist_del_init(&call->error_link); 198 200 spin_unlock_bh(&conn->params.peer->lock);
+7
net/rxrpc/peer_object.c
··· 228 228 seqlock_init(&peer->service_conn_lock); 229 229 spin_lock_init(&peer->lock); 230 230 peer->debug_id = atomic_inc_return(&rxrpc_debug_id); 231 + 232 + if (RXRPC_TX_SMSS > 2190) 233 + peer->cong_cwnd = 2; 234 + else if (RXRPC_TX_SMSS > 1095) 235 + peer->cong_cwnd = 3; 236 + else 237 + peer->cong_cwnd = 4; 231 238 } 232 239 233 240 _leave(" = %p", peer);