diff options
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/tcp.c | 2 | ||||
-rw-r--r-- | net/ipv4/tcp_ipv4.c | 8 | ||||
-rw-r--r-- | net/ipv4/tcp_output.c | 42 |
3 files changed, 27 insertions, 25 deletions
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index f115ea68a4ef..6adb1abf05e0 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
@@ -2246,7 +2246,7 @@ static int do_tcp_setsockopt(struct sock *sk, int level, | |||
2246 | /* Values greater than interface MTU won't take effect. However | 2246 | /* Values greater than interface MTU won't take effect. However |
2247 | * at the point when this call is done we typically don't yet | 2247 | * at the point when this call is done we typically don't yet |
2248 | * know which interface is going to be used */ | 2248 | * know which interface is going to be used */ |
2249 | if (val < 8 || val > MAX_TCP_WINDOW) { | 2249 | if (val < TCP_MIN_MSS || val > MAX_TCP_WINDOW) { |
2250 | err = -EINVAL; | 2250 | err = -EINVAL; |
2251 | break; | 2251 | break; |
2252 | } | 2252 | } |
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 020766292bb0..cb8d305cb5b4 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -415,6 +415,9 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info) | |||
415 | !icsk->icsk_backoff) | 415 | !icsk->icsk_backoff) |
416 | break; | 416 | break; |
417 | 417 | ||
418 | if (sock_owned_by_user(sk)) | ||
419 | break; | ||
420 | |||
418 | icsk->icsk_backoff--; | 421 | icsk->icsk_backoff--; |
419 | inet_csk(sk)->icsk_rto = __tcp_set_rto(tp) << | 422 | inet_csk(sk)->icsk_rto = __tcp_set_rto(tp) << |
420 | icsk->icsk_backoff; | 423 | icsk->icsk_backoff; |
@@ -429,11 +432,6 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info) | |||
429 | if (remaining) { | 432 | if (remaining) { |
430 | inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, | 433 | inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, |
431 | remaining, TCP_RTO_MAX); | 434 | remaining, TCP_RTO_MAX); |
432 | } else if (sock_owned_by_user(sk)) { | ||
433 | /* RTO revert clocked out retransmission, | ||
434 | * but socket is locked. Will defer. */ | ||
435 | inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, | ||
436 | HZ/20, TCP_RTO_MAX); | ||
437 | } else { | 435 | } else { |
438 | /* RTO revert clocked out retransmission. | 436 | /* RTO revert clocked out retransmission. |
439 | * Will retransmit now */ | 437 | * Will retransmit now */ |
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index de3bd8458588..7abecf73add9 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
@@ -237,11 +237,10 @@ void tcp_select_initial_window(int __space, __u32 mss, | |||
237 | /* when initializing use the value from init_rcv_wnd | 237 | /* when initializing use the value from init_rcv_wnd |
238 | * rather than the default from above | 238 | * rather than the default from above |
239 | */ | 239 | */ |
240 | if (init_rcv_wnd && | 240 | if (init_rcv_wnd) |
241 | (*rcv_wnd > init_rcv_wnd * mss)) | 241 | *rcv_wnd = min(*rcv_wnd, init_rcv_wnd * mss); |
242 | *rcv_wnd = init_rcv_wnd * mss; | 242 | else |
243 | else if (*rcv_wnd > init_cwnd * mss) | 243 | *rcv_wnd = min(*rcv_wnd, init_cwnd * mss); |
244 | *rcv_wnd = init_cwnd * mss; | ||
245 | } | 244 | } |
246 | 245 | ||
247 | /* Set the clamp no higher than max representable value */ | 246 | /* Set the clamp no higher than max representable value */ |
@@ -392,27 +391,30 @@ struct tcp_out_options { | |||
392 | */ | 391 | */ |
393 | static u8 tcp_cookie_size_check(u8 desired) | 392 | static u8 tcp_cookie_size_check(u8 desired) |
394 | { | 393 | { |
395 | if (desired > 0) { | 394 | int cookie_size; |
395 | |||
396 | if (desired > 0) | ||
396 | /* previously specified */ | 397 | /* previously specified */ |
397 | return desired; | 398 | return desired; |
398 | } | 399 | |
399 | if (sysctl_tcp_cookie_size <= 0) { | 400 | cookie_size = ACCESS_ONCE(sysctl_tcp_cookie_size); |
401 | if (cookie_size <= 0) | ||
400 | /* no default specified */ | 402 | /* no default specified */ |
401 | return 0; | 403 | return 0; |
402 | } | 404 | |
403 | if (sysctl_tcp_cookie_size <= TCP_COOKIE_MIN) { | 405 | if (cookie_size <= TCP_COOKIE_MIN) |
404 | /* value too small, specify minimum */ | 406 | /* value too small, specify minimum */ |
405 | return TCP_COOKIE_MIN; | 407 | return TCP_COOKIE_MIN; |
406 | } | 408 | |
407 | if (sysctl_tcp_cookie_size >= TCP_COOKIE_MAX) { | 409 | if (cookie_size >= TCP_COOKIE_MAX) |
408 | /* value too large, specify maximum */ | 410 | /* value too large, specify maximum */ |
409 | return TCP_COOKIE_MAX; | 411 | return TCP_COOKIE_MAX; |
410 | } | 412 | |
411 | if (0x1 & sysctl_tcp_cookie_size) { | 413 | if (cookie_size & 1) |
412 | /* 8-bit multiple, illegal, fix it */ | 414 | /* 8-bit multiple, illegal, fix it */ |
413 | return (u8)(sysctl_tcp_cookie_size + 0x1); | 415 | cookie_size++; |
414 | } | 416 | |
415 | return (u8)sysctl_tcp_cookie_size; | 417 | return (u8)cookie_size; |
416 | } | 418 | } |
417 | 419 | ||
418 | /* Write previously computed TCP options to the packet. | 420 | /* Write previously computed TCP options to the packet. |
@@ -1519,6 +1521,7 @@ static int tcp_tso_should_defer(struct sock *sk, struct sk_buff *skb) | |||
1519 | struct tcp_sock *tp = tcp_sk(sk); | 1521 | struct tcp_sock *tp = tcp_sk(sk); |
1520 | const struct inet_connection_sock *icsk = inet_csk(sk); | 1522 | const struct inet_connection_sock *icsk = inet_csk(sk); |
1521 | u32 send_win, cong_win, limit, in_flight; | 1523 | u32 send_win, cong_win, limit, in_flight; |
1524 | int win_divisor; | ||
1522 | 1525 | ||
1523 | if (TCP_SKB_CB(skb)->flags & TCPHDR_FIN) | 1526 | if (TCP_SKB_CB(skb)->flags & TCPHDR_FIN) |
1524 | goto send_now; | 1527 | goto send_now; |
@@ -1550,13 +1553,14 @@ static int tcp_tso_should_defer(struct sock *sk, struct sk_buff *skb) | |||
1550 | if ((skb != tcp_write_queue_tail(sk)) && (limit >= skb->len)) | 1553 | if ((skb != tcp_write_queue_tail(sk)) && (limit >= skb->len)) |
1551 | goto send_now; | 1554 | goto send_now; |
1552 | 1555 | ||
1553 | if (sysctl_tcp_tso_win_divisor) { | 1556 | win_divisor = ACCESS_ONCE(sysctl_tcp_tso_win_divisor); |
1557 | if (win_divisor) { | ||
1554 | u32 chunk = min(tp->snd_wnd, tp->snd_cwnd * tp->mss_cache); | 1558 | u32 chunk = min(tp->snd_wnd, tp->snd_cwnd * tp->mss_cache); |
1555 | 1559 | ||
1556 | /* If at least some fraction of a window is available, | 1560 | /* If at least some fraction of a window is available, |
1557 | * just use it. | 1561 | * just use it. |
1558 | */ | 1562 | */ |
1559 | chunk /= sysctl_tcp_tso_win_divisor; | 1563 | chunk /= win_divisor; |
1560 | if (limit >= chunk) | 1564 | if (limit >= chunk) |
1561 | goto send_now; | 1565 | goto send_now; |
1562 | } else { | 1566 | } else { |