@@ -1121,6 +1121,7 @@ struct mptcp_sendmsg_info {
u16 sent;
unsigned int flags;
bool data_lock_held;
+ struct mptcp_data_frag *last_frag;
};
static int mptcp_check_allowed_size(const struct mptcp_sock *msk, struct sock *ssk,
@@ -1511,6 +1512,19 @@ static void mptcp_update_post_push(struct mptcp_sock *msk,
msk->snd_nxt = snd_nxt_new;
}
+static void mptcp_update_first_pending(struct sock *sk, struct mptcp_sendmsg_info *info)
+{
+ struct mptcp_sock *msk = mptcp_sk(sk);
+
+ if (info->last_frag)
+ 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)
+{
+ mptcp_update_first_pending(sk, info);
+}
+
void mptcp_check_and_set_pending(struct sock *sk)
{
if (mptcp_send_head(sk))
@@ -1524,7 +1538,13 @@ static int __subflow_push_pending(struct sock *sk, struct sock *ssk,
struct mptcp_data_frag *dfrag;
int len, copied = 0, err = 0;
- while ((dfrag = mptcp_send_head(sk))) {
+ info->last_frag = NULL;
+
+ dfrag = mptcp_send_head(sk);
+ if (!dfrag)
+ goto out;
+
+ do {
info->sent = dfrag->already_sent;
info->limit = dfrag->data_len;
len = dfrag->data_len - dfrag->already_sent;
@@ -1543,7 +1563,8 @@ static int __subflow_push_pending(struct sock *sk, struct sock *ssk,
mptcp_update_post_push(msk, dfrag, ret);
}
- WRITE_ONCE(msk->first_pending, mptcp_send_next(sk));
+ info->last_frag = dfrag;
+ dfrag = mptcp_next_frag(sk, dfrag);
if (msk->snd_burst <= 0 ||
!sk_stream_memory_free(ssk) ||
@@ -1552,7 +1573,7 @@ static int __subflow_push_pending(struct sock *sk, struct sock *ssk,
goto out;
}
mptcp_set_timeout(sk);
- }
+ } while (dfrag);
err = copied;
out:
@@ -1598,6 +1619,7 @@ void __mptcp_push_pending(struct sock *sk, unsigned int flags)
ret = __subflow_push_pending(sk, ssk, &info);
if (ret <= 0) {
+ mptcp_update_first_pending(sk, &info);
if (ret == -EAGAIN &&
inet_sk_state_load(ssk) != TCP_CLOSE)
goto again;
@@ -1611,6 +1633,7 @@ void __mptcp_push_pending(struct sock *sk, unsigned int flags)
mptcp_subflow_set_scheduled(subflow, false);
}
}
+ mptcp_update_dfrags(sk, &info);
}
/* at this point we held the socket lock for the last subflow we used */
@@ -1644,12 +1667,14 @@ static void __mptcp_subflow_push_pending(struct sock *sk, struct sock *ssk, bool
ret = __subflow_push_pending(sk, ssk, &info);
first = false;
if (ret <= 0) {
+ mptcp_update_first_pending(sk, &info);
if (ret == -EAGAIN &&
inet_sk_state_load(ssk) != TCP_CLOSE)
goto again;
break;
}
msk->last_snd = ssk;
+ mptcp_update_dfrags(sk, &info);
continue;
}
@@ -1676,6 +1701,7 @@ static void __mptcp_subflow_push_pending(struct sock *sk, struct sock *ssk, bool
ret = __subflow_push_pending(sk, ssk, &info);
if (ret <= 0) {
+ mptcp_update_first_pending(sk, &info);
if (ret == -EAGAIN &&
inet_sk_state_load(ssk) != TCP_CLOSE)
goto again;
@@ -1687,6 +1713,7 @@ static void __mptcp_subflow_push_pending(struct sock *sk, struct sock *ssk, bool
mptcp_subflow_set_scheduled(subflow, false);
}
}
+ mptcp_update_dfrags(sk, &info);
}
out:
@@ -349,16 +349,23 @@ static inline struct mptcp_data_frag *mptcp_send_head(const struct sock *sk)
return READ_ONCE(msk->first_pending);
}
-static inline struct mptcp_data_frag *mptcp_send_next(struct sock *sk)
+static inline struct mptcp_data_frag *mptcp_next_frag(const struct sock *sk,
+ struct mptcp_data_frag *cur)
{
struct mptcp_sock *msk = mptcp_sk(sk);
- struct mptcp_data_frag *cur;
- cur = msk->first_pending;
+ if (!cur)
+ return NULL;
+
return list_is_last(&cur->list, &msk->rtx_queue) ? NULL :
list_next_entry(cur, list);
}
+static inline struct mptcp_data_frag *mptcp_send_next(const struct sock *sk)
+{
+ return mptcp_next_frag(sk, mptcp_send_head(sk));
+}
+
static inline struct mptcp_data_frag *mptcp_pending_tail(const struct sock *sk)
{
struct mptcp_sock *msk = mptcp_sk(sk);
To support redundant package schedulers more easily, this patch refactors the data sending loop in __subflow_push_pending(), to delay updating first_pending until all data are sent. Signed-off-by: Geliang Tang <geliang.tang@suse.com> --- net/mptcp/protocol.c | 33 ++++++++++++++++++++++++++++++--- net/mptcp/protocol.h | 13 ++++++++++--- 2 files changed, 40 insertions(+), 6 deletions(-)