aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_input.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/tcp_input.c')
-rw-r--r--net/ipv4/tcp_input.c70
1 files changed, 32 insertions, 38 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index b55f60f6fcbe..6d8ab1c4efc3 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -182,7 +182,7 @@ static void tcp_incr_quickack(struct sock *sk)
182 icsk->icsk_ack.quick = min(quickacks, TCP_MAX_QUICKACKS); 182 icsk->icsk_ack.quick = min(quickacks, TCP_MAX_QUICKACKS);
183} 183}
184 184
185void tcp_enter_quickack_mode(struct sock *sk) 185static void tcp_enter_quickack_mode(struct sock *sk)
186{ 186{
187 struct inet_connection_sock *icsk = inet_csk(sk); 187 struct inet_connection_sock *icsk = inet_csk(sk);
188 tcp_incr_quickack(sk); 188 tcp_incr_quickack(sk);
@@ -259,8 +259,11 @@ static void tcp_fixup_sndbuf(struct sock *sk)
259 int sndmem = tcp_sk(sk)->rx_opt.mss_clamp + MAX_TCP_HEADER + 16 + 259 int sndmem = tcp_sk(sk)->rx_opt.mss_clamp + MAX_TCP_HEADER + 16 +
260 sizeof(struct sk_buff); 260 sizeof(struct sk_buff);
261 261
262 if (sk->sk_sndbuf < 3 * sndmem) 262 if (sk->sk_sndbuf < 3 * sndmem) {
263 sk->sk_sndbuf = min(3 * sndmem, sysctl_tcp_wmem[2]); 263 sk->sk_sndbuf = 3 * sndmem;
264 if (sk->sk_sndbuf > sysctl_tcp_wmem[2])
265 sk->sk_sndbuf = sysctl_tcp_wmem[2];
266 }
264} 267}
265 268
266/* 2. Tuning advertised window (window_clamp, rcv_ssthresh) 269/* 2. Tuning advertised window (window_clamp, rcv_ssthresh)
@@ -396,7 +399,7 @@ static void tcp_clamp_window(struct sock *sk)
396 if (sk->sk_rcvbuf < sysctl_tcp_rmem[2] && 399 if (sk->sk_rcvbuf < sysctl_tcp_rmem[2] &&
397 !(sk->sk_userlocks & SOCK_RCVBUF_LOCK) && 400 !(sk->sk_userlocks & SOCK_RCVBUF_LOCK) &&
398 !tcp_memory_pressure && 401 !tcp_memory_pressure &&
399 atomic_read(&tcp_memory_allocated) < sysctl_tcp_mem[0]) { 402 atomic_long_read(&tcp_memory_allocated) < sysctl_tcp_mem[0]) {
400 sk->sk_rcvbuf = min(atomic_read(&sk->sk_rmem_alloc), 403 sk->sk_rcvbuf = min(atomic_read(&sk->sk_rmem_alloc),
401 sysctl_tcp_rmem[2]); 404 sysctl_tcp_rmem[2]);
402 } 405 }
@@ -428,10 +431,10 @@ EXPORT_SYMBOL(tcp_initialize_rcv_mss);
428 * 431 *
429 * The algorithm for RTT estimation w/o timestamps is based on 432 * The algorithm for RTT estimation w/o timestamps is based on
430 * Dynamic Right-Sizing (DRS) by Wu Feng and Mike Fisk of LANL. 433 * Dynamic Right-Sizing (DRS) by Wu Feng and Mike Fisk of LANL.
431 * <http://www.lanl.gov/radiant/website/pubs/drs/lacsi2001.ps> 434 * <http://public.lanl.gov/radiant/pubs.html#DRS>
432 * 435 *
433 * More detail on this code can be found at 436 * More detail on this code can be found at
434 * <http://www.psc.edu/~jheffner/senior_thesis.ps>, 437 * <http://staff.psc.edu/jheffner/>,
435 * though this reference is out of date. A new paper 438 * though this reference is out of date. A new paper
436 * is pending. 439 * is pending.
437 */ 440 */
@@ -805,25 +808,12 @@ void tcp_update_metrics(struct sock *sk)
805 } 808 }
806} 809}
807 810
808/* Numbers are taken from RFC3390.
809 *
810 * John Heffner states:
811 *
812 * The RFC specifies a window of no more than 4380 bytes
813 * unless 2*MSS > 4380. Reading the pseudocode in the RFC
814 * is a bit misleading because they use a clamp at 4380 bytes
815 * rather than use a multiplier in the relevant range.
816 */
817__u32 tcp_init_cwnd(struct tcp_sock *tp, struct dst_entry *dst) 811__u32 tcp_init_cwnd(struct tcp_sock *tp, struct dst_entry *dst)
818{ 812{
819 __u32 cwnd = (dst ? dst_metric(dst, RTAX_INITCWND) : 0); 813 __u32 cwnd = (dst ? dst_metric(dst, RTAX_INITCWND) : 0);
820 814
821 if (!cwnd) { 815 if (!cwnd)
822 if (tp->mss_cache > 1460) 816 cwnd = rfc3390_bytes_to_packets(tp->mss_cache);
823 cwnd = 2;
824 else
825 cwnd = (tp->mss_cache > 1095) ? 3 : 4;
826 }
827 return min_t(__u32, cwnd, tp->snd_cwnd_clamp); 817 return min_t(__u32, cwnd, tp->snd_cwnd_clamp);
828} 818}
829 819
@@ -2314,7 +2304,7 @@ static inline int tcp_dupack_heuristics(struct tcp_sock *tp)
2314 2304
2315static inline int tcp_skb_timedout(struct sock *sk, struct sk_buff *skb) 2305static inline int tcp_skb_timedout(struct sock *sk, struct sk_buff *skb)
2316{ 2306{
2317 return (tcp_time_stamp - TCP_SKB_CB(skb)->when > inet_csk(sk)->icsk_rto); 2307 return tcp_time_stamp - TCP_SKB_CB(skb)->when > inet_csk(sk)->icsk_rto;
2318} 2308}
2319 2309
2320static inline int tcp_head_timedout(struct sock *sk) 2310static inline int tcp_head_timedout(struct sock *sk)
@@ -2508,7 +2498,7 @@ static void tcp_timeout_skbs(struct sock *sk)
2508/* Mark head of queue up as lost. With RFC3517 SACK, the packets is 2498/* Mark head of queue up as lost. With RFC3517 SACK, the packets is
2509 * is against sacked "cnt", otherwise it's against facked "cnt" 2499 * is against sacked "cnt", otherwise it's against facked "cnt"
2510 */ 2500 */
2511static void tcp_mark_head_lost(struct sock *sk, int packets) 2501static void tcp_mark_head_lost(struct sock *sk, int packets, int mark_head)
2512{ 2502{
2513 struct tcp_sock *tp = tcp_sk(sk); 2503 struct tcp_sock *tp = tcp_sk(sk);
2514 struct sk_buff *skb; 2504 struct sk_buff *skb;
@@ -2516,13 +2506,13 @@ static void tcp_mark_head_lost(struct sock *sk, int packets)
2516 int err; 2506 int err;
2517 unsigned int mss; 2507 unsigned int mss;
2518 2508
2519 if (packets == 0)
2520 return;
2521
2522 WARN_ON(packets > tp->packets_out); 2509 WARN_ON(packets > tp->packets_out);
2523 if (tp->lost_skb_hint) { 2510 if (tp->lost_skb_hint) {
2524 skb = tp->lost_skb_hint; 2511 skb = tp->lost_skb_hint;
2525 cnt = tp->lost_cnt_hint; 2512 cnt = tp->lost_cnt_hint;
2513 /* Head already handled? */
2514 if (mark_head && skb != tcp_write_queue_head(sk))
2515 return;
2526 } else { 2516 } else {
2527 skb = tcp_write_queue_head(sk); 2517 skb = tcp_write_queue_head(sk);
2528 cnt = 0; 2518 cnt = 0;
@@ -2557,6 +2547,9 @@ static void tcp_mark_head_lost(struct sock *sk, int packets)
2557 } 2547 }
2558 2548
2559 tcp_skb_mark_lost(tp, skb); 2549 tcp_skb_mark_lost(tp, skb);
2550
2551 if (mark_head)
2552 break;
2560 } 2553 }
2561 tcp_verify_left_out(tp); 2554 tcp_verify_left_out(tp);
2562} 2555}
@@ -2568,17 +2561,18 @@ static void tcp_update_scoreboard(struct sock *sk, int fast_rexmit)
2568 struct tcp_sock *tp = tcp_sk(sk); 2561 struct tcp_sock *tp = tcp_sk(sk);
2569 2562
2570 if (tcp_is_reno(tp)) { 2563 if (tcp_is_reno(tp)) {
2571 tcp_mark_head_lost(sk, 1); 2564 tcp_mark_head_lost(sk, 1, 1);
2572 } else if (tcp_is_fack(tp)) { 2565 } else if (tcp_is_fack(tp)) {
2573 int lost = tp->fackets_out - tp->reordering; 2566 int lost = tp->fackets_out - tp->reordering;
2574 if (lost <= 0) 2567 if (lost <= 0)
2575 lost = 1; 2568 lost = 1;
2576 tcp_mark_head_lost(sk, lost); 2569 tcp_mark_head_lost(sk, lost, 0);
2577 } else { 2570 } else {
2578 int sacked_upto = tp->sacked_out - tp->reordering; 2571 int sacked_upto = tp->sacked_out - tp->reordering;
2579 if (sacked_upto < fast_rexmit) 2572 if (sacked_upto >= 0)
2580 sacked_upto = fast_rexmit; 2573 tcp_mark_head_lost(sk, sacked_upto, 0);
2581 tcp_mark_head_lost(sk, sacked_upto); 2574 else if (fast_rexmit)
2575 tcp_mark_head_lost(sk, 1, 1);
2582 } 2576 }
2583 2577
2584 tcp_timeout_skbs(sk); 2578 tcp_timeout_skbs(sk);
@@ -2887,7 +2881,7 @@ static void tcp_mtup_probe_success(struct sock *sk)
2887 icsk->icsk_mtup.probe_size; 2881 icsk->icsk_mtup.probe_size;
2888 tp->snd_cwnd_cnt = 0; 2882 tp->snd_cwnd_cnt = 0;
2889 tp->snd_cwnd_stamp = tcp_time_stamp; 2883 tp->snd_cwnd_stamp = tcp_time_stamp;
2890 tp->rcv_ssthresh = tcp_current_ssthresh(sk); 2884 tp->snd_ssthresh = tcp_current_ssthresh(sk);
2891 2885
2892 icsk->icsk_mtup.search_low = icsk->icsk_mtup.probe_size; 2886 icsk->icsk_mtup.search_low = icsk->icsk_mtup.probe_size;
2893 icsk->icsk_mtup.probe_size = 0; 2887 icsk->icsk_mtup.probe_size = 0;
@@ -2984,7 +2978,7 @@ static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked, int flag)
2984 before(tp->snd_una, tp->high_seq) && 2978 before(tp->snd_una, tp->high_seq) &&
2985 icsk->icsk_ca_state != TCP_CA_Open && 2979 icsk->icsk_ca_state != TCP_CA_Open &&
2986 tp->fackets_out > tp->reordering) { 2980 tp->fackets_out > tp->reordering) {
2987 tcp_mark_head_lost(sk, tp->fackets_out - tp->reordering); 2981 tcp_mark_head_lost(sk, tp->fackets_out - tp->reordering, 0);
2988 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPLOSS); 2982 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPLOSS);
2989 } 2983 }
2990 2984
@@ -3412,8 +3406,8 @@ static void tcp_ack_probe(struct sock *sk)
3412 3406
3413static inline int tcp_ack_is_dubious(const struct sock *sk, const int flag) 3407static inline int tcp_ack_is_dubious(const struct sock *sk, const int flag)
3414{ 3408{
3415 return (!(flag & FLAG_NOT_DUP) || (flag & FLAG_CA_ALERT) || 3409 return !(flag & FLAG_NOT_DUP) || (flag & FLAG_CA_ALERT) ||
3416 inet_csk(sk)->icsk_ca_state != TCP_CA_Open); 3410 inet_csk(sk)->icsk_ca_state != TCP_CA_Open;
3417} 3411}
3418 3412
3419static inline int tcp_may_raise_cwnd(const struct sock *sk, const int flag) 3413static inline int tcp_may_raise_cwnd(const struct sock *sk, const int flag)
@@ -3430,9 +3424,9 @@ static inline int tcp_may_update_window(const struct tcp_sock *tp,
3430 const u32 ack, const u32 ack_seq, 3424 const u32 ack, const u32 ack_seq,
3431 const u32 nwin) 3425 const u32 nwin)
3432{ 3426{
3433 return (after(ack, tp->snd_una) || 3427 return after(ack, tp->snd_una) ||
3434 after(ack_seq, tp->snd_wl1) || 3428 after(ack_seq, tp->snd_wl1) ||
3435 (ack_seq == tp->snd_wl1 && nwin > tp->snd_wnd)); 3429 (ack_seq == tp->snd_wl1 && nwin > tp->snd_wnd);
3436} 3430}
3437 3431
3438/* Update our send window. 3432/* Update our send window.
@@ -4870,7 +4864,7 @@ static int tcp_should_expand_sndbuf(struct sock *sk)
4870 return 0; 4864 return 0;
4871 4865
4872 /* If we are under soft global TCP memory pressure, do not expand. */ 4866 /* If we are under soft global TCP memory pressure, do not expand. */
4873 if (atomic_read(&tcp_memory_allocated) >= sysctl_tcp_mem[0]) 4867 if (atomic_long_read(&tcp_memory_allocated) >= sysctl_tcp_mem[0])
4874 return 0; 4868 return 0;
4875 4869
4876 /* If we filled the congestion window, do not expand. */ 4870 /* If we filled the congestion window, do not expand. */