提交 51466a75 编写于 作者: E Eric Dumazet 提交者: David S. Miller

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: NEric Dumazet <edumazet@google.com>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 a7eea416
...@@ -1316,16 +1316,12 @@ static bool tcp_shifted_skb(struct sock *sk, struct sk_buff *skb, ...@@ -1316,16 +1316,12 @@ static bool tcp_shifted_skb(struct sock *sk, struct sk_buff *skb,
* code can come after this skb later on it's better to keep * code can come after this skb later on it's better to keep
* setting gso_size to something. * setting gso_size to something.
*/ */
if (!skb_shinfo(prev)->gso_size) { if (!skb_shinfo(prev)->gso_size)
skb_shinfo(prev)->gso_size = mss; skb_shinfo(prev)->gso_size = mss;
skb_shinfo(prev)->gso_type = sk->sk_gso_type;
}
/* CHECKME: To clear or not to clear? Mimics normal skb currently */ /* CHECKME: To clear or not to clear? Mimics normal skb currently */
if (tcp_skb_pcount(skb) <= 1) { if (tcp_skb_pcount(skb) <= 1)
skb_shinfo(skb)->gso_size = 0; skb_shinfo(skb)->gso_size = 0;
skb_shinfo(skb)->gso_type = 0;
}
/* Difference in this won't matter, both ACKed by the same cumul. ACK */ /* Difference in this won't matter, both ACKed by the same cumul. ACK */
TCP_SKB_CB(prev)->sacked |= (TCP_SKB_CB(skb)->sacked & TCPCB_EVER_RETRANS); TCP_SKB_CB(prev)->sacked |= (TCP_SKB_CB(skb)->sacked & TCPCB_EVER_RETRANS);
......
...@@ -412,7 +412,6 @@ static void tcp_init_nondata_skb(struct sk_buff *skb, u32 seq, u8 flags) ...@@ -412,7 +412,6 @@ static void tcp_init_nondata_skb(struct sk_buff *skb, u32 seq, u8 flags)
tcp_skb_pcount_set(skb, 1); tcp_skb_pcount_set(skb, 1);
shinfo->gso_size = 0; shinfo->gso_size = 0;
shinfo->gso_type = 0;
TCP_SKB_CB(skb)->seq = seq; TCP_SKB_CB(skb)->seq = seq;
if (flags & (TCPHDR_SYN | TCPHDR_FIN)) 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,6 +1002,7 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
} }
tcp_options_write((__be32 *)(th + 1), tp, &opts); tcp_options_write((__be32 *)(th + 1), tp, &opts);
skb_shinfo(skb)->gso_type = sk->sk_gso_type;
if (likely((tcb->tcp_flags & TCPHDR_SYN) == 0)) if (likely((tcb->tcp_flags & TCPHDR_SYN) == 0))
tcp_ecn_send(sk, skb, tcp_header_size); tcp_ecn_send(sk, skb, tcp_header_size);
...@@ -1080,11 +1080,9 @@ static void tcp_set_skb_tso_segs(const struct sock *sk, struct sk_buff *skb, ...@@ -1080,11 +1080,9 @@ static void tcp_set_skb_tso_segs(const struct sock *sk, struct sk_buff *skb,
*/ */
tcp_skb_pcount_set(skb, 1); tcp_skb_pcount_set(skb, 1);
shinfo->gso_size = 0; shinfo->gso_size = 0;
shinfo->gso_type = 0;
} else { } else {
tcp_skb_pcount_set(skb, DIV_ROUND_UP(skb->len, mss_now)); tcp_skb_pcount_set(skb, DIV_ROUND_UP(skb->len, mss_now));
shinfo->gso_size = mss_now; shinfo->gso_size = mss_now;
shinfo->gso_type = sk->sk_gso_type;
} }
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册