spin_unlock_bh(&msk->join_list_lock);
 }
 
+static void mptcp_set_timeout(const struct sock *sk, const struct sock *ssk)
+{
+       long tout = ssk && inet_csk(ssk)->icsk_pending ?
+                                     inet_csk(ssk)->icsk_timeout - jiffies : 0;
+
+       if (tout <= 0)
+               tout = mptcp_sk(sk)->timer_ival;
+       mptcp_sk(sk)->timer_ival = tout > 0 ? tout : TCP_RTO_MIN;
+}
+
+static bool mptcp_timer_pending(struct sock *sk)
+{
+       return timer_pending(&inet_csk(sk)->icsk_retransmit_timer);
+}
+
+static void mptcp_reset_timer(struct sock *sk)
+{
+       struct inet_connection_sock *icsk = inet_csk(sk);
+       unsigned long tout;
+
+       /* should never be called with mptcp level timer cleared */
+       tout = READ_ONCE(mptcp_sk(sk)->timer_ival);
+       if (WARN_ON_ONCE(!tout))
+               tout = TCP_RTO_MIN;
+       sk_reset_timer(sk, &icsk->icsk_retransmit_timer, jiffies + tout);
+}
+
+void mptcp_data_acked(struct sock *sk)
+{
+       mptcp_reset_timer(sk);
+}
+
+static void mptcp_stop_timer(struct sock *sk)
+{
+       struct inet_connection_sock *icsk = inet_csk(sk);
+
+       sk_stop_timer(sk, &icsk->icsk_retransmit_timer);
+       mptcp_sk(sk)->timer_ival = 0;
+}
+
 static bool mptcp_ext_cache_refill(struct mptcp_sock *msk)
 {
        if (!msk->cached_ext)
                copied += ret;
        }
 
+       mptcp_set_timeout(sk, ssk);
        if (copied) {
                ret = copied;
                tcp_push(ssk, msg->msg_flags, mss_now, tcp_sk(ssk)->nonagle,
                         size_goal);
+
+               /* start the timer, if it's not pending */
+               if (!mptcp_timer_pending(sk))
+                       mptcp_reset_timer(sk);
        }
 
        ssk_check_wmem(msk, ssk);
        return copied;
 }
 
+static void mptcp_retransmit_handler(struct sock *sk)
+{
+       struct mptcp_sock *msk = mptcp_sk(sk);
+
+       if (atomic64_read(&msk->snd_una) == msk->write_seq)
+               mptcp_stop_timer(sk);
+       else
+               mptcp_reset_timer(sk);
+}
+
+static void mptcp_retransmit_timer(struct timer_list *t)
+{
+       struct inet_connection_sock *icsk = from_timer(icsk, t,
+                                                      icsk_retransmit_timer);
+       struct sock *sk = &icsk->icsk_inet.sk;
+
+       bh_lock_sock(sk);
+       if (!sock_owned_by_user(sk)) {
+               mptcp_retransmit_handler(sk);
+       } else {
+               /* delegate our work to tcp_release_cb() */
+               if (!test_and_set_bit(TCP_WRITE_TIMER_DEFERRED,
+                                     &sk->sk_tsq_flags))
+                       sock_hold(sk);
+       }
+       bh_unlock_sock(sk);
+       sock_put(sk);
+}
+
 /* subflow sockets can be either outgoing (connect) or incoming
  * (accept).
  *
 
        mptcp_pm_data_init(msk);
 
+       /* re-use the csk retrans timer for MPTCP-level retrans */
+       timer_setup(&msk->sk.icsk_retransmit_timer, mptcp_retransmit_timer, 0);
+
        return 0;
 }
 
        struct mptcp_sock *msk = mptcp_sk(sk);
        struct mptcp_data_frag *dtmp, *dfrag;
 
+       sk_stop_timer(sk, &msk->sk.icsk_retransmit_timer);
+
        list_for_each_entry_safe(dfrag, dtmp, &msk->rtx_queue, list)
                dfrag_clear(dfrag);
 }
        return -EOPNOTSUPP;
 }
 
-#define MPTCP_DEFERRED_ALL TCPF_DELACK_TIMER_DEFERRED
+#define MPTCP_DEFERRED_ALL (TCPF_DELACK_TIMER_DEFERRED | \
+                           TCPF_WRITE_TIMER_DEFERRED)
 
 /* this is very alike tcp_release_cb() but we must handle differently a
  * different set of events
                nflags = flags & ~MPTCP_DEFERRED_ALL;
        } while (cmpxchg(&sk->sk_tsq_flags, flags, nflags) != flags);
 
+       sock_release_ownership(sk);
+
        if (flags & TCPF_DELACK_TIMER_DEFERRED) {
                struct mptcp_sock *msk = mptcp_sk(sk);
                struct sock *ssk;
                if (!ssk || !schedule_work(&msk->work))
                        __sock_put(sk);
        }
+
+       if (flags & TCPF_WRITE_TIMER_DEFERRED) {
+               mptcp_retransmit_handler(sk);
+               __sock_put(sk);
+       }
 }
 
 static int mptcp_get_port(struct sock *sk, unsigned short snum)