Skip to content

Commit b51f9b8

Browse files
Paolo Abenidavem330
authored andcommitted
mptcp: introduce MPTCP retransmission timer
The timer will be used to schedule retransmission. It's frequency is based on the current subflow RTO estimation and is reset on every una_seq update The timer is clearer for good by __mptcp_clear_xmit() Also clean MPTCP rtx queue before each transmission. Signed-off-by: Paolo Abeni <pabeni@redhat.com> Signed-off-by: Mat Martineau <mathew.j.martineau@linux.intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 18b683b commit b51f9b8

File tree

3 files changed

+93
-2
lines changed

3 files changed

+93
-2
lines changed

net/mptcp/options.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -779,8 +779,10 @@ static void update_una(struct mptcp_sock *msk,
779779
snd_una = old_snd_una;
780780
old_snd_una = atomic64_cmpxchg(&msk->snd_una, snd_una,
781781
new_snd_una);
782-
if (old_snd_una == snd_una)
782+
if (old_snd_una == snd_una) {
783+
mptcp_data_acked((struct sock *)msk);
783784
break;
785+
}
784786
}
785787
}
786788

net/mptcp/protocol.c

Lines changed: 88 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,46 @@ static void __mptcp_flush_join_list(struct mptcp_sock *msk)
251251
spin_unlock_bh(&msk->join_list_lock);
252252
}
253253

254+
static void mptcp_set_timeout(const struct sock *sk, const struct sock *ssk)
255+
{
256+
long tout = ssk && inet_csk(ssk)->icsk_pending ?
257+
inet_csk(ssk)->icsk_timeout - jiffies : 0;
258+
259+
if (tout <= 0)
260+
tout = mptcp_sk(sk)->timer_ival;
261+
mptcp_sk(sk)->timer_ival = tout > 0 ? tout : TCP_RTO_MIN;
262+
}
263+
264+
static bool mptcp_timer_pending(struct sock *sk)
265+
{
266+
return timer_pending(&inet_csk(sk)->icsk_retransmit_timer);
267+
}
268+
269+
static void mptcp_reset_timer(struct sock *sk)
270+
{
271+
struct inet_connection_sock *icsk = inet_csk(sk);
272+
unsigned long tout;
273+
274+
/* should never be called with mptcp level timer cleared */
275+
tout = READ_ONCE(mptcp_sk(sk)->timer_ival);
276+
if (WARN_ON_ONCE(!tout))
277+
tout = TCP_RTO_MIN;
278+
sk_reset_timer(sk, &icsk->icsk_retransmit_timer, jiffies + tout);
279+
}
280+
281+
void mptcp_data_acked(struct sock *sk)
282+
{
283+
mptcp_reset_timer(sk);
284+
}
285+
286+
static void mptcp_stop_timer(struct sock *sk)
287+
{
288+
struct inet_connection_sock *icsk = inet_csk(sk);
289+
290+
sk_stop_timer(sk, &icsk->icsk_retransmit_timer);
291+
mptcp_sk(sk)->timer_ival = 0;
292+
}
293+
254294
static bool mptcp_ext_cache_refill(struct mptcp_sock *msk)
255295
{
256296
if (!msk->cached_ext)
@@ -596,10 +636,15 @@ static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
596636
copied += ret;
597637
}
598638

639+
mptcp_set_timeout(sk, ssk);
599640
if (copied) {
600641
ret = copied;
601642
tcp_push(ssk, msg->msg_flags, mss_now, tcp_sk(ssk)->nonagle,
602643
size_goal);
644+
645+
/* start the timer, if it's not pending */
646+
if (!mptcp_timer_pending(sk))
647+
mptcp_reset_timer(sk);
603648
}
604649

605650
ssk_check_wmem(msk, ssk);
@@ -787,6 +832,35 @@ static int mptcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
787832
return copied;
788833
}
789834

835+
static void mptcp_retransmit_handler(struct sock *sk)
836+
{
837+
struct mptcp_sock *msk = mptcp_sk(sk);
838+
839+
if (atomic64_read(&msk->snd_una) == msk->write_seq)
840+
mptcp_stop_timer(sk);
841+
else
842+
mptcp_reset_timer(sk);
843+
}
844+
845+
static void mptcp_retransmit_timer(struct timer_list *t)
846+
{
847+
struct inet_connection_sock *icsk = from_timer(icsk, t,
848+
icsk_retransmit_timer);
849+
struct sock *sk = &icsk->icsk_inet.sk;
850+
851+
bh_lock_sock(sk);
852+
if (!sock_owned_by_user(sk)) {
853+
mptcp_retransmit_handler(sk);
854+
} else {
855+
/* delegate our work to tcp_release_cb() */
856+
if (!test_and_set_bit(TCP_WRITE_TIMER_DEFERRED,
857+
&sk->sk_tsq_flags))
858+
sock_hold(sk);
859+
}
860+
bh_unlock_sock(sk);
861+
sock_put(sk);
862+
}
863+
790864
/* subflow sockets can be either outgoing (connect) or incoming
791865
* (accept).
792866
*
@@ -846,6 +920,9 @@ static int __mptcp_init_sock(struct sock *sk)
846920

847921
mptcp_pm_data_init(msk);
848922

923+
/* re-use the csk retrans timer for MPTCP-level retrans */
924+
timer_setup(&msk->sk.icsk_retransmit_timer, mptcp_retransmit_timer, 0);
925+
849926
return 0;
850927
}
851928

@@ -867,6 +944,8 @@ static void __mptcp_clear_xmit(struct sock *sk)
867944
struct mptcp_sock *msk = mptcp_sk(sk);
868945
struct mptcp_data_frag *dtmp, *dfrag;
869946

947+
sk_stop_timer(sk, &msk->sk.icsk_retransmit_timer);
948+
870949
list_for_each_entry_safe(dfrag, dtmp, &msk->rtx_queue, list)
871950
dfrag_clear(dfrag);
872951
}
@@ -1155,7 +1234,8 @@ static int mptcp_getsockopt(struct sock *sk, int level, int optname,
11551234
return -EOPNOTSUPP;
11561235
}
11571236

1158-
#define MPTCP_DEFERRED_ALL TCPF_DELACK_TIMER_DEFERRED
1237+
#define MPTCP_DEFERRED_ALL (TCPF_DELACK_TIMER_DEFERRED | \
1238+
TCPF_WRITE_TIMER_DEFERRED)
11591239

11601240
/* this is very alike tcp_release_cb() but we must handle differently a
11611241
* different set of events
@@ -1171,6 +1251,8 @@ static void mptcp_release_cb(struct sock *sk)
11711251
nflags = flags & ~MPTCP_DEFERRED_ALL;
11721252
} while (cmpxchg(&sk->sk_tsq_flags, flags, nflags) != flags);
11731253

1254+
sock_release_ownership(sk);
1255+
11741256
if (flags & TCPF_DELACK_TIMER_DEFERRED) {
11751257
struct mptcp_sock *msk = mptcp_sk(sk);
11761258
struct sock *ssk;
@@ -1179,6 +1261,11 @@ static void mptcp_release_cb(struct sock *sk)
11791261
if (!ssk || !schedule_work(&msk->work))
11801262
__sock_put(sk);
11811263
}
1264+
1265+
if (flags & TCPF_WRITE_TIMER_DEFERRED) {
1266+
mptcp_retransmit_handler(sk);
1267+
__sock_put(sk);
1268+
}
11821269
}
11831270

11841271
static int mptcp_get_port(struct sock *sk, unsigned short snum)

net/mptcp/protocol.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ struct mptcp_sock {
157157
u64 write_seq;
158158
u64 ack_seq;
159159
atomic64_t snd_una;
160+
unsigned long timer_ival;
160161
u32 token;
161162
unsigned long flags;
162163
bool can_ack;
@@ -326,6 +327,7 @@ void mptcp_get_options(const struct sk_buff *skb,
326327
void mptcp_finish_connect(struct sock *sk);
327328
void mptcp_data_ready(struct sock *sk, struct sock *ssk);
328329
bool mptcp_finish_join(struct sock *sk);
330+
void mptcp_data_acked(struct sock *sk);
329331

330332
int mptcp_token_new_request(struct request_sock *req);
331333
void mptcp_token_destroy_request(u32 token);

0 commit comments

Comments
 (0)