diff options
Diffstat (limited to 'net/ipv4/tcp_input.c')
-rw-r--r-- | net/ipv4/tcp_input.c | 36 |
1 files changed, 27 insertions, 9 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 00a41499d52c..a12b455928e5 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -68,6 +68,7 @@ | |||
68 | #include <linux/module.h> | 68 | #include <linux/module.h> |
69 | #include <linux/sysctl.h> | 69 | #include <linux/sysctl.h> |
70 | #include <linux/kernel.h> | 70 | #include <linux/kernel.h> |
71 | #include <linux/prefetch.h> | ||
71 | #include <net/dst.h> | 72 | #include <net/dst.h> |
72 | #include <net/tcp.h> | 73 | #include <net/tcp.h> |
73 | #include <net/inet_common.h> | 74 | #include <net/inet_common.h> |
@@ -3029,6 +3030,21 @@ static u32 tcp_tso_acked(struct sock *sk, struct sk_buff *skb) | |||
3029 | return packets_acked; | 3030 | return packets_acked; |
3030 | } | 3031 | } |
3031 | 3032 | ||
3033 | static void tcp_ack_tstamp(struct sock *sk, struct sk_buff *skb, | ||
3034 | u32 prior_snd_una) | ||
3035 | { | ||
3036 | const struct skb_shared_info *shinfo; | ||
3037 | |||
3038 | /* Avoid cache line misses to get skb_shinfo() and shinfo->tx_flags */ | ||
3039 | if (likely(!(sk->sk_tsflags & SOF_TIMESTAMPING_TX_ACK))) | ||
3040 | return; | ||
3041 | |||
3042 | shinfo = skb_shinfo(skb); | ||
3043 | if ((shinfo->tx_flags & SKBTX_ACK_TSTAMP) && | ||
3044 | between(shinfo->tskey, prior_snd_una, tcp_sk(sk)->snd_una - 1)) | ||
3045 | __skb_tstamp_tx(skb, NULL, sk, SCM_TSTAMP_ACK); | ||
3046 | } | ||
3047 | |||
3032 | /* Remove acknowledged frames from the retransmission queue. If our packet | 3048 | /* Remove acknowledged frames from the retransmission queue. If our packet |
3033 | * is before the ack sequence we can discard it as it's confirmed to have | 3049 | * is before the ack sequence we can discard it as it's confirmed to have |
3034 | * arrived at the other end. | 3050 | * arrived at the other end. |
@@ -3052,14 +3068,11 @@ static int tcp_clean_rtx_queue(struct sock *sk, int prior_fackets, | |||
3052 | first_ackt.v64 = 0; | 3068 | first_ackt.v64 = 0; |
3053 | 3069 | ||
3054 | while ((skb = tcp_write_queue_head(sk)) && skb != tcp_send_head(sk)) { | 3070 | while ((skb = tcp_write_queue_head(sk)) && skb != tcp_send_head(sk)) { |
3055 | struct skb_shared_info *shinfo = skb_shinfo(skb); | ||
3056 | struct tcp_skb_cb *scb = TCP_SKB_CB(skb); | 3071 | struct tcp_skb_cb *scb = TCP_SKB_CB(skb); |
3057 | u8 sacked = scb->sacked; | 3072 | u8 sacked = scb->sacked; |
3058 | u32 acked_pcount; | 3073 | u32 acked_pcount; |
3059 | 3074 | ||
3060 | if (unlikely(shinfo->tx_flags & SKBTX_ACK_TSTAMP) && | 3075 | tcp_ack_tstamp(sk, skb, prior_snd_una); |
3061 | between(shinfo->tskey, prior_snd_una, tp->snd_una - 1)) | ||
3062 | __skb_tstamp_tx(skb, NULL, sk, SCM_TSTAMP_ACK); | ||
3063 | 3076 | ||
3064 | /* Determine how many packets and what bytes were acked, tso and else */ | 3077 | /* Determine how many packets and what bytes were acked, tso and else */ |
3065 | if (after(scb->end_seq, tp->snd_una)) { | 3078 | if (after(scb->end_seq, tp->snd_una)) { |
@@ -3073,10 +3086,12 @@ static int tcp_clean_rtx_queue(struct sock *sk, int prior_fackets, | |||
3073 | 3086 | ||
3074 | fully_acked = false; | 3087 | fully_acked = false; |
3075 | } else { | 3088 | } else { |
3089 | /* Speedup tcp_unlink_write_queue() and next loop */ | ||
3090 | prefetchw(skb->next); | ||
3076 | acked_pcount = tcp_skb_pcount(skb); | 3091 | acked_pcount = tcp_skb_pcount(skb); |
3077 | } | 3092 | } |
3078 | 3093 | ||
3079 | if (sacked & TCPCB_RETRANS) { | 3094 | if (unlikely(sacked & TCPCB_RETRANS)) { |
3080 | if (sacked & TCPCB_SACKED_RETRANS) | 3095 | if (sacked & TCPCB_SACKED_RETRANS) |
3081 | tp->retrans_out -= acked_pcount; | 3096 | tp->retrans_out -= acked_pcount; |
3082 | flag |= FLAG_RETRANS_DATA_ACKED; | 3097 | flag |= FLAG_RETRANS_DATA_ACKED; |
@@ -3107,7 +3122,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, int prior_fackets, | |||
3107 | * connection startup slow start one packet too | 3122 | * connection startup slow start one packet too |
3108 | * quickly. This is severely frowned upon behavior. | 3123 | * quickly. This is severely frowned upon behavior. |
3109 | */ | 3124 | */ |
3110 | if (!(scb->tcp_flags & TCPHDR_SYN)) { | 3125 | if (likely(!(scb->tcp_flags & TCPHDR_SYN))) { |
3111 | flag |= FLAG_DATA_ACKED; | 3126 | flag |= FLAG_DATA_ACKED; |
3112 | } else { | 3127 | } else { |
3113 | flag |= FLAG_SYN_ACKED; | 3128 | flag |= FLAG_SYN_ACKED; |
@@ -3119,9 +3134,9 @@ static int tcp_clean_rtx_queue(struct sock *sk, int prior_fackets, | |||
3119 | 3134 | ||
3120 | tcp_unlink_write_queue(skb, sk); | 3135 | tcp_unlink_write_queue(skb, sk); |
3121 | sk_wmem_free_skb(sk, skb); | 3136 | sk_wmem_free_skb(sk, skb); |
3122 | if (skb == tp->retransmit_skb_hint) | 3137 | if (unlikely(skb == tp->retransmit_skb_hint)) |
3123 | tp->retransmit_skb_hint = NULL; | 3138 | tp->retransmit_skb_hint = NULL; |
3124 | if (skb == tp->lost_skb_hint) | 3139 | if (unlikely(skb == tp->lost_skb_hint)) |
3125 | tp->lost_skb_hint = NULL; | 3140 | tp->lost_skb_hint = NULL; |
3126 | } | 3141 | } |
3127 | 3142 | ||
@@ -3132,7 +3147,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, int prior_fackets, | |||
3132 | flag |= FLAG_SACK_RENEGING; | 3147 | flag |= FLAG_SACK_RENEGING; |
3133 | 3148 | ||
3134 | skb_mstamp_get(&now); | 3149 | skb_mstamp_get(&now); |
3135 | if (first_ackt.v64) { | 3150 | if (likely(first_ackt.v64)) { |
3136 | seq_rtt_us = skb_mstamp_us_delta(&now, &first_ackt); | 3151 | seq_rtt_us = skb_mstamp_us_delta(&now, &first_ackt); |
3137 | ca_seq_rtt_us = skb_mstamp_us_delta(&now, &last_ackt); | 3152 | ca_seq_rtt_us = skb_mstamp_us_delta(&now, &last_ackt); |
3138 | } | 3153 | } |
@@ -3394,6 +3409,9 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag) | |||
3394 | int acked = 0; /* Number of packets newly acked */ | 3409 | int acked = 0; /* Number of packets newly acked */ |
3395 | long sack_rtt_us = -1L; | 3410 | long sack_rtt_us = -1L; |
3396 | 3411 | ||
3412 | /* We very likely will need to access write queue head. */ | ||
3413 | prefetchw(sk->sk_write_queue.next); | ||
3414 | |||
3397 | /* If the ack is older than previous acks | 3415 | /* If the ack is older than previous acks |
3398 | * then we can probably ignore it. | 3416 | * then we can probably ignore it. |
3399 | */ | 3417 | */ |