aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/tcp.c')
-rw-r--r--net/ipv4/tcp.c59
1 files changed, 46 insertions, 13 deletions
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 64d0af675823..98440ad82558 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -326,6 +326,43 @@ void tcp_enter_memory_pressure(struct sock *sk)
326 326
327EXPORT_SYMBOL(tcp_enter_memory_pressure); 327EXPORT_SYMBOL(tcp_enter_memory_pressure);
328 328
329/* Convert seconds to retransmits based on initial and max timeout */
330static u8 secs_to_retrans(int seconds, int timeout, int rto_max)
331{
332 u8 res = 0;
333
334 if (seconds > 0) {
335 int period = timeout;
336
337 res = 1;
338 while (seconds > period && res < 255) {
339 res++;
340 timeout <<= 1;
341 if (timeout > rto_max)
342 timeout = rto_max;
343 period += timeout;
344 }
345 }
346 return res;
347}
348
349/* Convert retransmits to seconds based on initial and max timeout */
350static int retrans_to_secs(u8 retrans, int timeout, int rto_max)
351{
352 int period = 0;
353
354 if (retrans > 0) {
355 period = timeout;
356 while (--retrans) {
357 timeout <<= 1;
358 if (timeout > rto_max)
359 timeout = rto_max;
360 period += timeout;
361 }
362 }
363 return period;
364}
365
329/* 366/*
330 * Wait for a TCP event. 367 * Wait for a TCP event.
331 * 368 *
@@ -1405,7 +1442,9 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
1405 goto found_ok_skb; 1442 goto found_ok_skb;
1406 if (tcp_hdr(skb)->fin) 1443 if (tcp_hdr(skb)->fin)
1407 goto found_fin_ok; 1444 goto found_fin_ok;
1408 WARN_ON(!(flags & MSG_PEEK)); 1445 WARN(!(flags & MSG_PEEK), KERN_INFO "recvmsg bug 2: "
1446 "copied %X seq %X\n", *seq,
1447 TCP_SKB_CB(skb)->seq);
1409 } 1448 }
1410 1449
1411 /* Well, if we have backlog, try to process it now yet. */ 1450 /* Well, if we have backlog, try to process it now yet. */
@@ -2163,16 +2202,10 @@ static int do_tcp_setsockopt(struct sock *sk, int level,
2163 break; 2202 break;
2164 2203
2165 case TCP_DEFER_ACCEPT: 2204 case TCP_DEFER_ACCEPT:
2166 icsk->icsk_accept_queue.rskq_defer_accept = 0; 2205 /* Translate value in seconds to number of retransmits */
2167 if (val > 0) { 2206 icsk->icsk_accept_queue.rskq_defer_accept =
2168 /* Translate value in seconds to number of 2207 secs_to_retrans(val, TCP_TIMEOUT_INIT / HZ,
2169 * retransmits */ 2208 TCP_RTO_MAX / HZ);
2170 while (icsk->icsk_accept_queue.rskq_defer_accept < 32 &&
2171 val > ((TCP_TIMEOUT_INIT / HZ) <<
2172 icsk->icsk_accept_queue.rskq_defer_accept))
2173 icsk->icsk_accept_queue.rskq_defer_accept++;
2174 icsk->icsk_accept_queue.rskq_defer_accept++;
2175 }
2176 break; 2209 break;
2177 2210
2178 case TCP_WINDOW_CLAMP: 2211 case TCP_WINDOW_CLAMP:
@@ -2353,8 +2386,8 @@ static int do_tcp_getsockopt(struct sock *sk, int level,
2353 val = (val ? : sysctl_tcp_fin_timeout) / HZ; 2386 val = (val ? : sysctl_tcp_fin_timeout) / HZ;
2354 break; 2387 break;
2355 case TCP_DEFER_ACCEPT: 2388 case TCP_DEFER_ACCEPT:
2356 val = !icsk->icsk_accept_queue.rskq_defer_accept ? 0 : 2389 val = retrans_to_secs(icsk->icsk_accept_queue.rskq_defer_accept,
2357 ((TCP_TIMEOUT_INIT / HZ) << (icsk->icsk_accept_queue.rskq_defer_accept - 1)); 2390 TCP_TIMEOUT_INIT / HZ, TCP_RTO_MAX / HZ);
2358 break; 2391 break;
2359 case TCP_WINDOW_CLAMP: 2392 case TCP_WINDOW_CLAMP:
2360 val = tp->window_clamp; 2393 val = tp->window_clamp;