[PATCH mptcp-next v2 3/5] mptcp: add call_again flag in mptcp_sched_ops

Geliang Tang posted 5 patches 3 years, 9 months ago
There is a newer version of this series
[PATCH mptcp-next v2 3/5] mptcp: add call_again flag in mptcp_sched_ops
Posted by Geliang Tang 3 years, 9 months ago
This patch adds call_again flag in struct mptcp_sched_ops, init it as
true. Set it to false when the scheduler set call_again = true over
MPTCP_SUBFLOWS_MAX times to avoid infinite loops.

Signed-off-by: Geliang Tang <geliang.tang@suse.com>
---
 include/net/mptcp.h  |  1 +
 net/mptcp/protocol.c | 21 +++++++++++++++------
 net/mptcp/sched.c    |  1 +
 3 files changed, 17 insertions(+), 6 deletions(-)

diff --git a/include/net/mptcp.h b/include/net/mptcp.h
index d48c66de8466..8c9991ef591a 100644
--- a/include/net/mptcp.h
+++ b/include/net/mptcp.h
@@ -112,6 +112,7 @@ struct mptcp_sched_ops {
 	char			name[MPTCP_SCHED_NAME_MAX];
 	struct module		*owner;
 	struct list_head	list;
+	bool			call_again;
 
 	void (*init)(const struct mptcp_sock *msk);
 	void (*release)(const struct mptcp_sock *msk);
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 1105c8ad670f..9c1ebd7a507e 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -1560,6 +1560,7 @@ void __mptcp_push_pending(struct sock *sk, unsigned int flags)
 	int len, copied = 0;
 	bool call_again;
 	int max = 0;
+	int nr = 0;
 
 	while ((dfrag = mptcp_send_head(sk))) {
 		info.sent = dfrag->already_sent;
@@ -1587,7 +1588,7 @@ void __mptcp_push_pending(struct sock *sk, unsigned int flags)
 				lock_sock(ssk);
 
 			ret = mptcp_sendmsg_frag(sk, ssk, dfrag, &info);
-			if (ret <= 0 && !call_again) {
+			if (ret <= 0 && (!call_again || !msk->sched->call_again)) {
 				mptcp_push_release(ssk, &info);
 				goto out;
 			}
@@ -1595,16 +1596,20 @@ void __mptcp_push_pending(struct sock *sk, unsigned int flags)
 			if (ret > max)
 				max = ret;
 
-			if (!call_again) {
+			if (!call_again || !msk->sched->call_again) {
 				info.sent += max;
 				copied += max;
 				len -= max;
 
 				mptcp_update_post_push(msk, dfrag, max);
 				max = 0;
+			} else if (nr++ >= MPTCP_SUBFLOWS_MAX) {
+				mptcp_push_release(ssk, &info);
+				WRITE_ONCE(msk->sched->call_again, false);
+				goto out;
 			}
 		}
-		if (!call_again)
+		if (!call_again || !msk->sched->call_again)
 			WRITE_ONCE(msk->first_pending, mptcp_send_next(sk));
 	}
 
@@ -1632,6 +1637,7 @@ static void __mptcp_subflow_push_pending(struct sock *sk, struct sock *ssk)
 	int len, copied = 0;
 	bool first = true;
 	int max = 0;
+	int nr = 0;
 
 	info.flags = 0;
 	while ((dfrag = mptcp_send_head(sk))) {
@@ -1655,23 +1661,26 @@ static void __mptcp_subflow_push_pending(struct sock *sk, struct sock *ssk)
 			}
 
 			ret = mptcp_sendmsg_frag(sk, ssk, dfrag, &info);
-			if (ret <= 0 && !call_again)
+			if (ret <= 0 && (!call_again || !msk->sched->call_again))
 				goto out;
 
 			if (ret > max)
 				max = ret;
 
 			first = false;
-			if (!call_again) {
+			if (!call_again || !msk->sched->call_again) {
 				info.sent += max;
 				copied += max;
 				len -= max;
 
 				mptcp_update_post_push(msk, dfrag, max);
 				max = 0;
+			} else if (nr++ >= MPTCP_SUBFLOWS_MAX) {
+				WRITE_ONCE(msk->sched->call_again, false);
+				goto out;
 			}
 		}
-		if (!call_again)
+		if (!call_again || !msk->sched->call_again)
 			WRITE_ONCE(msk->first_pending, mptcp_send_next(sk));
 	}
 
diff --git a/net/mptcp/sched.c b/net/mptcp/sched.c
index 0d5fc96a2ce0..10736c334ab0 100644
--- a/net/mptcp/sched.c
+++ b/net/mptcp/sched.c
@@ -67,6 +67,7 @@ int mptcp_init_sched(struct mptcp_sock *msk,
 	msk->sched = sched;
 	if (msk->sched->init)
 		msk->sched->init(msk);
+	WRITE_ONCE(msk->sched->call_again, true);
 
 	pr_debug("sched=%s", msk->sched->name);
 
-- 
2.34.1