struct timer_list                   icsk_delack_timer      read_mostly                             inet_csk_reset_xmit_timer,tcp_connect
 u32                                 icsk_rto               read_write                              tcp_cwnd_validate,tcp_schedule_loss_probe,tcp_connect_init,tcp_connect,tcp_write_xmit,tcp_push_one
 u32                                 icsk_rto_min
+u32                                 icsk_rto_max           read_mostly                             tcp_reset_xmit_timer
 u32                                 icsk_delack_max
 u32                                 icsk_pmtu_cookie       read_write                              tcp_sync_mss,tcp_current_mss,tcp_send_syn_data,tcp_connect_init,tcp_connect
 struct tcp_congestion_ops           icsk_ca_ops            read_write                              tcp_cwnd_validate,tcp_tso_segs,tcp_ca_dst_init,tcp_connect_init,tcp_connect,tcp_write_xmit
 
        struct timer_list         icsk_delack_timer;
        __u32                     icsk_rto;
        __u32                     icsk_rto_min;
+       u32                       icsk_rto_max;
        __u32                     icsk_delack_max;
        __u32                     icsk_pmtu_cookie;
        const struct tcp_congestion_ops *icsk_ca_ops;
 
 #define TCP_DELACK_MIN 4U
 #define TCP_ATO_MIN    4U
 #endif
-#define TCP_RTO_MAX    ((unsigned)(120*HZ))
-#define TCP_RTO_MIN    ((unsigned)(HZ/5))
+#define TCP_RTO_MAX_SEC 120
+#define TCP_RTO_MAX    ((unsigned)(TCP_RTO_MAX_SEC * HZ))
+#define TCP_RTO_MIN    ((unsigned)(HZ / 5))
 #define TCP_TIMEOUT_MIN        (2U) /* Min timeout for TCP timers in jiffies */
 
 #define TCP_TIMEOUT_MIN_US (2*USEC_PER_MSEC) /* Min TCP timeout in microsecs */
 int tcp_mss_to_mtu(struct sock *sk, int mss);
 void tcp_mtup_init(struct sock *sk);
 
+static inline unsigned int tcp_rto_max(const struct sock *sk)
+{
+       return READ_ONCE(inet_csk(sk)->icsk_rto_max);
+}
+
 static inline void tcp_bound_rto(struct sock *sk)
 {
-       if (inet_csk(sk)->icsk_rto > TCP_RTO_MAX)
-               inet_csk(sk)->icsk_rto = TCP_RTO_MAX;
+       inet_csk(sk)->icsk_rto = min(inet_csk(sk)->icsk_rto, tcp_rto_max(sk));
 }
 
 static inline u32 __tcp_set_rto(const struct tcp_sock *tp)
 {
        if (pace_delay)
                when += tcp_pacing_delay(sk);
-       inet_csk_reset_xmit_timer(sk, what, when, TCP_RTO_MAX);
+       inet_csk_reset_xmit_timer(sk, what, when,
+                                 tcp_rto_max(sk));
 }
 
 /* Something is really bad, we could not queue an additional packet,
 
 #define TCP_AO_REPAIR          42      /* Get/Set SNEs and ISNs */
 
 #define TCP_IS_MPTCP           43      /* Is MPTCP being used? */
+#define TCP_RTO_MAX_MS         44      /* max rto time in ms */
 
 #define TCP_REPAIR_ON          1
 #define TCP_REPAIR_OFF         0
 
        INIT_LIST_HEAD(&tp->tsorted_sent_queue);
 
        icsk->icsk_rto = TCP_TIMEOUT_INIT;
+
+       /* Use a sysctl ? */
+       icsk->icsk_rto_max = TCP_RTO_MAX;
+
        rto_min_us = READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_rto_min_us);
        icsk->icsk_rto_min = usecs_to_jiffies(rto_min_us);
        icsk->icsk_delack_max = TCP_DELACK_MAX;
                           secs_to_retrans(val, TCP_TIMEOUT_INIT / HZ,
                                           TCP_RTO_MAX / HZ));
                return 0;
+       case TCP_RTO_MAX_MS:
+               if (val < MSEC_PER_SEC || val > TCP_RTO_MAX_SEC * MSEC_PER_SEC)
+                       return -EINVAL;
+               WRITE_ONCE(inet_csk(sk)->icsk_rto_max, msecs_to_jiffies(val));
+               return 0;
        }
 
        sockopt_lock_sock(sk);
        case TCP_IS_MPTCP:
                val = 0;
                break;
+       case TCP_RTO_MAX_MS:
+               val = jiffies_to_msecs(tcp_rto_max(sk));
+               break;
        default:
                return -ENOPROTOOPT;
        }
 
                 * This function is not for random using!
                 */
        } else {
-               unsigned long when = tcp_probe0_when(sk, TCP_RTO_MAX);
+               unsigned long when = tcp_probe0_when(sk, tcp_rto_max(sk));
 
                when = tcp_clamp_probe0_to_user_timeout(sk, when);
                tcp_reset_xmit_timer(sk, ICSK_TIME_PROBE0, when, true);
 
 
        icsk->icsk_backoff--;
        icsk->icsk_rto = tp->srtt_us ? __tcp_set_rto(tp) : TCP_TIMEOUT_INIT;
-       icsk->icsk_rto = inet_csk_rto_backoff(icsk, TCP_RTO_MAX);
+       icsk->icsk_rto = inet_csk_rto_backoff(icsk, tcp_rto_max(sk));
 
        tcp_mstamp_refresh(tp);
        delta_us = (u32)(tp->tcp_mstamp - tcp_skb_timestamp_us(skb));
 
                unsigned long delay;
 
                delay = TCP_DELACK_MAX << icsk->icsk_ack.retry;
-               if (delay < TCP_RTO_MAX)
+               if (delay < tcp_rto_max(sk))
                        icsk->icsk_ack.retry++;
                inet_csk_schedule_ack(sk);
                icsk->icsk_ack.ato = TCP_ATO_MIN;
        if (err <= 0) {
                if (icsk->icsk_backoff < READ_ONCE(net->ipv4.sysctl_tcp_retries2))
                        icsk->icsk_backoff++;
-               timeout = tcp_probe0_when(sk, TCP_RTO_MAX);
+               timeout = tcp_probe0_when(sk, tcp_rto_max(sk));
        } else {
                /* If packet was not sent due to local congestion,
                 * Let senders fight for local resources conservatively.
 
 
        /* If peer does not open window for long time, or did not transmit
         * anything for long time, penalize it. */
-       if ((s32)(tcp_jiffies32 - tp->lsndtime) > 2*TCP_RTO_MAX || !do_reset)
+       if ((s32)(tcp_jiffies32 - tp->lsndtime) > 2*tcp_rto_max(sk) || !do_reset)
                shift++;
 
        /* If some dubious ICMP arrived, penalize even more. */
 {
        unsigned int linear_backoff_thresh, timeout;
 
-       linear_backoff_thresh = ilog2(TCP_RTO_MAX / rto_base);
+       linear_backoff_thresh = ilog2(tcp_rto_max(sk) / rto_base);
        if (boundary <= linear_backoff_thresh)
                timeout = ((2 << boundary) - 1) * rto_base;
        else
                timeout = ((2 << linear_backoff_thresh) - 1) * rto_base +
-                       (boundary - linear_backoff_thresh) * TCP_RTO_MAX;
+                       (boundary - linear_backoff_thresh) * tcp_rto_max(sk);
        return jiffies_to_msecs(timeout);
 }
 /**
 
                retry_until = READ_ONCE(net->ipv4.sysctl_tcp_retries2);
                if (sock_flag(sk, SOCK_DEAD)) {
-                       const bool alive = icsk->icsk_rto < TCP_RTO_MAX;
+                       const bool alive = icsk->icsk_rto < tcp_rto_max(sk);
 
                        retry_until = tcp_orphan_retries(sk, alive);
                        do_reset = alive ||
        }
        max_probes = READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_retries2);
        if (sock_flag(sk, SOCK_DEAD)) {
-               const bool alive = inet_csk_rto_backoff(icsk, TCP_RTO_MAX) < TCP_RTO_MAX;
+               unsigned int rto_max = tcp_rto_max(sk);
+               const bool alive = inet_csk_rto_backoff(icsk, rto_max) < rto_max;
 
                max_probes = tcp_orphan_retries(sk, alive);
                if (!alive && icsk->icsk_backoff >= max_probes)
        const struct inet_connection_sock *icsk = inet_csk(sk);
        u32 user_timeout = READ_ONCE(icsk->icsk_user_timeout);
        const struct tcp_sock *tp = tcp_sk(sk);
-       int timeout = TCP_RTO_MAX * 2;
+       int timeout = tcp_rto_max(sk) * 2;
        s32 rcv_delta;
 
        if (user_timeout) {
                icsk->icsk_backoff = 0;
                icsk->icsk_rto = clamp(__tcp_set_rto(tp),
                                       tcp_rto_min(sk),
-                                      TCP_RTO_MAX);
+                                      tcp_rto_max(sk));
        } else if (sk->sk_state != TCP_SYN_SENT ||
                   tp->total_rto >
                   READ_ONCE(net->ipv4.sysctl_tcp_syn_linear_timeouts)) {
                 * activated.
                 */
                icsk->icsk_backoff++;
-               icsk->icsk_rto = min(icsk->icsk_rto << 1, TCP_RTO_MAX);
+               icsk->icsk_rto = min(icsk->icsk_rto << 1, tcp_rto_max(sk));
        }
        tcp_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
                             tcp_clamp_rto_to_user_timeout(sk), false);