|
@@ -326,6 +326,43 @@ void tcp_enter_memory_pressure(struct sock *sk)
|
|
|
|
|
|
EXPORT_SYMBOL(tcp_enter_memory_pressure);
|
|
EXPORT_SYMBOL(tcp_enter_memory_pressure);
|
|
|
|
|
|
|
|
+/* Convert seconds to retransmits based on initial and max timeout */
|
|
|
|
+static u8 secs_to_retrans(int seconds, int timeout, int rto_max)
|
|
|
|
+{
|
|
|
|
+ u8 res = 0;
|
|
|
|
+
|
|
|
|
+ if (seconds > 0) {
|
|
|
|
+ int period = timeout;
|
|
|
|
+
|
|
|
|
+ res = 1;
|
|
|
|
+ while (seconds > period && res < 255) {
|
|
|
|
+ res++;
|
|
|
|
+ timeout <<= 1;
|
|
|
|
+ if (timeout > rto_max)
|
|
|
|
+ timeout = rto_max;
|
|
|
|
+ period += timeout;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return res;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* Convert retransmits to seconds based on initial and max timeout */
|
|
|
|
+static int retrans_to_secs(u8 retrans, int timeout, int rto_max)
|
|
|
|
+{
|
|
|
|
+ int period = 0;
|
|
|
|
+
|
|
|
|
+ if (retrans > 0) {
|
|
|
|
+ period = timeout;
|
|
|
|
+ while (--retrans) {
|
|
|
|
+ timeout <<= 1;
|
|
|
|
+ if (timeout > rto_max)
|
|
|
|
+ timeout = rto_max;
|
|
|
|
+ period += timeout;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return period;
|
|
|
|
+}
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* Wait for a TCP event.
|
|
* Wait for a TCP event.
|
|
*
|
|
*
|
|
@@ -2163,16 +2200,10 @@ static int do_tcp_setsockopt(struct sock *sk, int level,
|
|
break;
|
|
break;
|
|
|
|
|
|
case TCP_DEFER_ACCEPT:
|
|
case TCP_DEFER_ACCEPT:
|
|
- icsk->icsk_accept_queue.rskq_defer_accept = 0;
|
|
|
|
- if (val > 0) {
|
|
|
|
- /* Translate value in seconds to number of
|
|
|
|
- * retransmits */
|
|
|
|
- while (icsk->icsk_accept_queue.rskq_defer_accept < 32 &&
|
|
|
|
- val > ((TCP_TIMEOUT_INIT / HZ) <<
|
|
|
|
- icsk->icsk_accept_queue.rskq_defer_accept))
|
|
|
|
- icsk->icsk_accept_queue.rskq_defer_accept++;
|
|
|
|
- icsk->icsk_accept_queue.rskq_defer_accept++;
|
|
|
|
- }
|
|
|
|
|
|
+ /* Translate value in seconds to number of retransmits */
|
|
|
|
+ icsk->icsk_accept_queue.rskq_defer_accept =
|
|
|
|
+ secs_to_retrans(val, TCP_TIMEOUT_INIT / HZ,
|
|
|
|
+ TCP_RTO_MAX / HZ);
|
|
break;
|
|
break;
|
|
|
|
|
|
case TCP_WINDOW_CLAMP:
|
|
case TCP_WINDOW_CLAMP:
|
|
@@ -2353,8 +2384,8 @@ static int do_tcp_getsockopt(struct sock *sk, int level,
|
|
val = (val ? : sysctl_tcp_fin_timeout) / HZ;
|
|
val = (val ? : sysctl_tcp_fin_timeout) / HZ;
|
|
break;
|
|
break;
|
|
case TCP_DEFER_ACCEPT:
|
|
case TCP_DEFER_ACCEPT:
|
|
- val = !icsk->icsk_accept_queue.rskq_defer_accept ? 0 :
|
|
|
|
- ((TCP_TIMEOUT_INIT / HZ) << (icsk->icsk_accept_queue.rskq_defer_accept - 1));
|
|
|
|
|
|
+ val = retrans_to_secs(icsk->icsk_accept_queue.rskq_defer_accept,
|
|
|
|
+ TCP_TIMEOUT_INIT / HZ, TCP_RTO_MAX / HZ);
|
|
break;
|
|
break;
|
|
case TCP_WINDOW_CLAMP:
|
|
case TCP_WINDOW_CLAMP:
|
|
val = tp->window_clamp;
|
|
val = tp->window_clamp;
|