This patch adds a new member info_sent in struct mptcp_data_frag, save
info->sent in it, to support delay updating already_sent of dfrag until
all data are sent.
Signed-off-by: Geliang Tang <geliang.tang@suse.com>
---
net/mptcp/protocol.c | 29 ++++++++++++++++++++++++-----
net/mptcp/protocol.h | 1 +
2 files changed, 25 insertions(+), 5 deletions(-)
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 262853d51e40..54863644e3ea 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -1108,6 +1108,7 @@ mptcp_carve_data_frag(const struct mptcp_sock *msk, struct page_frag *pfrag,
dfrag->data_seq = msk->write_seq;
dfrag->overhead = offset - orig_offset + sizeof(struct mptcp_data_frag);
dfrag->offset = offset + sizeof(struct mptcp_data_frag);
+ dfrag->sent = 0;
dfrag->already_sent = 0;
dfrag->page = pfrag->page;
@@ -1493,11 +1494,11 @@ static void mptcp_update_post_push(struct mptcp_sock *msk,
{
u64 snd_nxt_new = dfrag->data_seq;
- dfrag->already_sent += sent;
+ dfrag->sent += sent;
msk->snd_burst -= sent;
- snd_nxt_new += dfrag->already_sent;
+ snd_nxt_new += dfrag->sent;
/* snd_nxt_new can be smaller than snd_nxt in case mptcp
* is recovering after a failover. In that event, this re-sends
@@ -1520,6 +1521,23 @@ static void mptcp_update_first_pending(struct sock *sk, struct mptcp_sendmsg_inf
WRITE_ONCE(msk->first_pending, mptcp_next_frag(sk, info->last_frag));
}
+static void mptcp_update_dfrags(struct sock *sk, struct mptcp_sendmsg_info *info)
+{
+ struct mptcp_data_frag *dfrag = mptcp_send_head(sk);
+
+ if (!dfrag)
+ return;
+
+ do {
+ if (dfrag->sent) {
+ dfrag->already_sent = max(dfrag->already_sent, dfrag->sent);
+ dfrag->sent = 0;
+ }
+ } while ((dfrag = mptcp_next_frag(sk, dfrag)));
+
+ mptcp_update_first_pending(sk, info);
+}
+
void mptcp_check_and_set_pending(struct sock *sk)
{
if (mptcp_send_head(sk))
@@ -1543,6 +1561,7 @@ static int __subflow_push_pending(struct sock *sk, struct sock *ssk,
info->sent = dfrag->already_sent;
info->limit = dfrag->data_len;
len = dfrag->data_len - dfrag->already_sent;
+ dfrag->sent = info->sent;
while (len > 0) {
int ret = 0;
@@ -1617,7 +1636,7 @@ void __mptcp_push_pending(struct sock *sk, unsigned int flags)
mptcp_subflow_set_scheduled(subflow, false);
}
}
- mptcp_update_first_pending(sk, &info);
+ mptcp_update_dfrags(sk, &info);
}
/* at this point we held the socket lock for the last subflow we used */
@@ -1657,7 +1676,7 @@ static void __mptcp_subflow_push_pending(struct sock *sk, struct sock *ssk, bool
break;
}
msk->last_snd = ssk;
- mptcp_update_first_pending(sk, &info);
+ mptcp_update_dfrags(sk, &info);
continue;
}
@@ -1687,7 +1706,7 @@ static void __mptcp_subflow_push_pending(struct sock *sk, struct sock *ssk, bool
mptcp_subflow_set_scheduled(subflow, false);
}
}
- mptcp_update_first_pending(sk, &info);
+ mptcp_update_dfrags(sk, &info);
}
out:
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index b2b5110a2aba..93932488f70b 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -241,6 +241,7 @@ struct mptcp_data_frag {
u16 data_len;
u16 offset;
u16 overhead;
+ u16 sent;
u16 already_sent;
struct page *page;
};
--
2.35.3