diff options
| -rw-r--r-- | net/ipv4/tcp.c | 55 |
1 files changed, 43 insertions, 12 deletions
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 64d0af675823..9b2756fbdf9b 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 | ||
| 327 | EXPORT_SYMBOL(tcp_enter_memory_pressure); | 327 | EXPORT_SYMBOL(tcp_enter_memory_pressure); |
| 328 | 328 | ||
| 329 | /* Convert seconds to retransmits based on initial and max timeout */ | ||
| 330 | static 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 */ | ||
| 350 | static 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 | * |
| @@ -2163,16 +2200,10 @@ static int do_tcp_setsockopt(struct sock *sk, int level, | |||
| 2163 | break; | 2200 | break; |
| 2164 | 2201 | ||
| 2165 | case TCP_DEFER_ACCEPT: | 2202 | case TCP_DEFER_ACCEPT: |
| 2166 | icsk->icsk_accept_queue.rskq_defer_accept = 0; | 2203 | /* Translate value in seconds to number of retransmits */ |
| 2167 | if (val > 0) { | 2204 | icsk->icsk_accept_queue.rskq_defer_accept = |
| 2168 | /* Translate value in seconds to number of | 2205 | secs_to_retrans(val, TCP_TIMEOUT_INIT / HZ, |
| 2169 | * retransmits */ | 2206 | 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; | 2207 | break; |
| 2177 | 2208 | ||
| 2178 | case TCP_WINDOW_CLAMP: | 2209 | case TCP_WINDOW_CLAMP: |
| @@ -2353,8 +2384,8 @@ static int do_tcp_getsockopt(struct sock *sk, int level, | |||
| 2353 | val = (val ? : sysctl_tcp_fin_timeout) / HZ; | 2384 | val = (val ? : sysctl_tcp_fin_timeout) / HZ; |
| 2354 | break; | 2385 | break; |
| 2355 | case TCP_DEFER_ACCEPT: | 2386 | case TCP_DEFER_ACCEPT: |
| 2356 | val = !icsk->icsk_accept_queue.rskq_defer_accept ? 0 : | 2387 | val = retrans_to_secs(icsk->icsk_accept_queue.rskq_defer_accept, |
| 2357 | ((TCP_TIMEOUT_INIT / HZ) << (icsk->icsk_accept_queue.rskq_defer_accept - 1)); | 2388 | TCP_TIMEOUT_INIT / HZ, TCP_RTO_MAX / HZ); |
| 2358 | break; | 2389 | break; |
| 2359 | case TCP_WINDOW_CLAMP: | 2390 | case TCP_WINDOW_CLAMP: |
| 2360 | val = tp->window_clamp; | 2391 | val = tp->window_clamp; |
