aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2015-06-11 12:15:16 -0400
committerDavid S. Miller <davem@davemloft.net>2015-06-11 19:33:11 -0400
commit51466a7545b73b7ad7bcfb33410d2823ccfaa501 (patch)
treef12fe132349a599b567efc45a092bbf2f591ea3d /net
parenta7eea416cb08a514f94c0ca5ff30c18783fab054 (diff)
tcp: fill shinfo->gso_type at last moment
Our goal is to touch skb_shinfo(skb) only when absolutely needed, to avoid two cache line misses in TCP output path for last skb that is considered but not sent because of various conditions (cwnd, tso defer, receiver window, TSQ...) A packet is GSO only when skb_shinfo(skb)->gso_size is not zero. We can set skb_shinfo(skb)->gso_type to sk->sk_gso_type even for non GSO packets. Signed-off-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/ipv4/tcp_input.c8
-rw-r--r--net/ipv4/tcp_output.c4
2 files changed, 3 insertions, 9 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index d4f76ab6e136..70a6fa8ecbd3 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -1316,16 +1316,12 @@ static bool tcp_shifted_skb(struct sock *sk, struct sk_buff *skb,
1316 * code can come after this skb later on it's better to keep 1316 * code can come after this skb later on it's better to keep
1317 * setting gso_size to something. 1317 * setting gso_size to something.
1318 */ 1318 */
1319 if (!skb_shinfo(prev)->gso_size) { 1319 if (!skb_shinfo(prev)->gso_size)
1320 skb_shinfo(prev)->gso_size = mss; 1320 skb_shinfo(prev)->gso_size = mss;
1321 skb_shinfo(prev)->gso_type = sk->sk_gso_type;
1322 }
1323 1321
1324 /* CHECKME: To clear or not to clear? Mimics normal skb currently */ 1322 /* CHECKME: To clear or not to clear? Mimics normal skb currently */
1325 if (tcp_skb_pcount(skb) <= 1) { 1323 if (tcp_skb_pcount(skb) <= 1)
1326 skb_shinfo(skb)->gso_size = 0; 1324 skb_shinfo(skb)->gso_size = 0;
1327 skb_shinfo(skb)->gso_type = 0;
1328 }
1329 1325
1330 /* Difference in this won't matter, both ACKed by the same cumul. ACK */ 1326 /* Difference in this won't matter, both ACKed by the same cumul. ACK */
1331 TCP_SKB_CB(prev)->sacked |= (TCP_SKB_CB(skb)->sacked & TCPCB_EVER_RETRANS); 1327 TCP_SKB_CB(prev)->sacked |= (TCP_SKB_CB(skb)->sacked & TCPCB_EVER_RETRANS);
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index eeb59befaf06..a51f7aab27d6 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -412,7 +412,6 @@ static void tcp_init_nondata_skb(struct sk_buff *skb, u32 seq, u8 flags)
412 412
413 tcp_skb_pcount_set(skb, 1); 413 tcp_skb_pcount_set(skb, 1);
414 shinfo->gso_size = 0; 414 shinfo->gso_size = 0;
415 shinfo->gso_type = 0;
416 415
417 TCP_SKB_CB(skb)->seq = seq; 416 TCP_SKB_CB(skb)->seq = seq;
418 if (flags & (TCPHDR_SYN | TCPHDR_FIN)) 417 if (flags & (TCPHDR_SYN | TCPHDR_FIN))
@@ -1003,6 +1002,7 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
1003 } 1002 }
1004 1003
1005 tcp_options_write((__be32 *)(th + 1), tp, &opts); 1004 tcp_options_write((__be32 *)(th + 1), tp, &opts);
1005 skb_shinfo(skb)->gso_type = sk->sk_gso_type;
1006 if (likely((tcb->tcp_flags & TCPHDR_SYN) == 0)) 1006 if (likely((tcb->tcp_flags & TCPHDR_SYN) == 0))
1007 tcp_ecn_send(sk, skb, tcp_header_size); 1007 tcp_ecn_send(sk, skb, tcp_header_size);
1008 1008
@@ -1080,11 +1080,9 @@ static void tcp_set_skb_tso_segs(const struct sock *sk, struct sk_buff *skb,
1080 */ 1080 */
1081 tcp_skb_pcount_set(skb, 1); 1081 tcp_skb_pcount_set(skb, 1);
1082 shinfo->gso_size = 0; 1082 shinfo->gso_size = 0;
1083 shinfo->gso_type = 0;
1084 } else { 1083 } else {
1085 tcp_skb_pcount_set(skb, DIV_ROUND_UP(skb->len, mss_now)); 1084 tcp_skb_pcount_set(skb, DIV_ROUND_UP(skb->len, mss_now));
1086 shinfo->gso_size = mss_now; 1085 shinfo->gso_size = mss_now;
1087 shinfo->gso_type = sk->sk_gso_type;
1088 } 1086 }
1089} 1087}
1090 1088