All of lore.kernel.org
 help / color / mirror / Atom feed
From: Geliang Tang <geliang.tang@suse.com>
To: mptcp@lists.linux.dev
Cc: Geliang Tang <geliang.tang@suse.com>
Subject: [PATCH mptcp-next v3 14/15] selftests/bpf: Add bpf_burst scheduler
Date: Tue, 30 May 2023 21:17:34 +0800	[thread overview]
Message-ID: <bd209c2426adc1a210b1ded5fc87f42dc833d632.1685452619.git.geliang.tang@suse.com> (raw)
In-Reply-To: <cover.1685452619.git.geliang.tang@suse.com>

This patch implements the burst BPF MPTCP scheduler, named bpf_burst,
which is the default scheduler in protocol.c.

Signed-off-by: Geliang Tang <geliang.tang@suse.com>
---
 tools/testing/selftests/bpf/bpf_tcp_helpers.h |   3 +
 .../selftests/bpf/progs/mptcp_bpf_burst.c     | 195 ++++++++++++++++++
 2 files changed, 198 insertions(+)
 create mode 100644 tools/testing/selftests/bpf/progs/mptcp_bpf_burst.c

diff --git a/tools/testing/selftests/bpf/bpf_tcp_helpers.h b/tools/testing/selftests/bpf/bpf_tcp_helpers.h
index dddb51a47740..d42a0c00ed73 100644
--- a/tools/testing/selftests/bpf/bpf_tcp_helpers.h
+++ b/tools/testing/selftests/bpf/bpf_tcp_helpers.h
@@ -234,12 +234,15 @@ extern void tcp_cong_avoid_ai(struct tcp_sock *tp, __u32 w, __u32 acked) __ksym;
 #define MPTCP_SUBFLOWS_MAX	8
 
 struct mptcp_subflow_context {
+	unsigned long avg_pacing_rate;
 	__u32	backup : 1;
+	__u8	stale_count;
 	struct	sock *tcp_sock;	    /* tcp sk backpointer */
 } __attribute__((preserve_access_index));
 
 struct mptcp_sched_data {
 	struct sock	*last_snd;
+	int		snd_burst;
 	bool		reinject;
 	struct mptcp_subflow_context *contexts[MPTCP_SUBFLOWS_MAX];
 } __attribute__((preserve_access_index));
diff --git a/tools/testing/selftests/bpf/progs/mptcp_bpf_burst.c b/tools/testing/selftests/bpf/progs/mptcp_bpf_burst.c
new file mode 100644
index 000000000000..305829162ce5
--- /dev/null
+++ b/tools/testing/selftests/bpf/progs/mptcp_bpf_burst.c
@@ -0,0 +1,195 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2023, SUSE. */
+
+#include <linux/bpf.h>
+#include <limits.h>
+#include "bpf_tcp_helpers.h"
+
+char _license[] SEC("license") = "GPL";
+
+struct subflow_send_info {
+	struct sock *ssk;
+	__u64 linger_time;
+};
+
+static inline struct sock *
+mptcp_subflow_tcp_sock(const struct mptcp_subflow_context *subflow)
+{
+	return subflow->tcp_sock;
+}
+
+extern bool mptcp_subflow_active(struct mptcp_subflow_context *subflow) __ksym;
+extern long mptcp_timeout_from_subflow(const struct mptcp_subflow_context *subflow) __ksym;
+extern void mptcp_set_timer(struct sock *sk, long tout) __ksym;
+extern bool mptcp_stream_memory_free(struct mptcp_subflow_context *subflow) __ksym;
+extern __u64 mptcp_get_linger_time(struct sock *ssk, __u32 pace) __ksym;
+extern __u32 mptcp_get_burst(const struct mptcp_sock *msk) __ksym;
+extern unsigned long mptcp_get_pacing_rate(struct mptcp_subflow_context *subflow, __u32 burst) __ksym;
+extern bool mptcp_rtx_and_write_queues_empty(const struct sock *sk) __ksym;
+extern void mptcp_pm_subflow_chk_stale(const struct mptcp_sock *msk, struct sock *ssk) __ksym;
+
+#define SSK_MODE_ACTIVE	0
+#define SSK_MODE_BACKUP	1
+#define SSK_MODE_MAX	2
+
+SEC("struct_ops/mptcp_sched_burst_init")
+void BPF_PROG(mptcp_sched_burst_init, const struct mptcp_sock *msk)
+{
+}
+
+SEC("struct_ops/mptcp_sched_burst_release")
+void BPF_PROG(mptcp_sched_burst_release, const struct mptcp_sock *msk)
+{
+}
+
+void BPF_STRUCT_OPS(bpf_burst_data_init, const struct mptcp_sock *msk,
+		    struct mptcp_sched_data *data)
+{
+	mptcp_sched_data_set_contexts(msk, data);
+}
+
+static int bpf_burst_get_send(const struct mptcp_sock *msk,
+			      struct mptcp_sched_data *data)
+{
+	struct subflow_send_info send_info[SSK_MODE_MAX];
+	struct mptcp_subflow_context *subflow;
+	struct sock *sk = (struct sock *)msk;
+	int i, nr_active = 0;
+	__u32 pace, burst;
+	__u64 linger_time;
+	struct sock *ssk;
+	long tout = 0;
+	int nr = 0;
+
+	/* pick the subflow with the lower wmem/wspace ratio */
+	for (i = 0; i < SSK_MODE_MAX; ++i) {
+		send_info[i].ssk = NULL;
+		send_info[i].linger_time = -1;
+	}
+
+	for (i = 0; i < MPTCP_SUBFLOWS_MAX; i++) {
+		if (!data->contexts[i])
+			break;
+
+		subflow = data->contexts[i];
+		ssk = mptcp_subflow_tcp_sock(subflow);
+		if (!mptcp_subflow_active(subflow))
+			continue;
+
+		tout = max(tout, mptcp_timeout_from_subflow(subflow));
+		nr_active += !subflow->backup;
+		pace = subflow->avg_pacing_rate;
+		if (!pace) {
+			/* init pacing rate from socket */
+			subflow->avg_pacing_rate = ssk->sk_pacing_rate;
+			pace = subflow->avg_pacing_rate;
+			if (!pace)
+				continue;
+		}
+
+		linger_time = mptcp_get_linger_time(ssk, pace);
+		if (linger_time < send_info[subflow->backup].linger_time) {
+			send_info[subflow->backup].ssk = ssk;
+			send_info[subflow->backup].linger_time = linger_time;
+		}
+	}
+	mptcp_set_timer(sk, tout);
+
+	/* pick the best backup if no other subflow is active */
+	if (!nr_active)
+		send_info[SSK_MODE_ACTIVE].ssk = send_info[SSK_MODE_BACKUP].ssk;
+
+	ssk = send_info[SSK_MODE_ACTIVE].ssk;
+	if (!ssk)
+		return -1;
+
+	for (i = 0; i < MPTCP_SUBFLOWS_MAX; i++) {
+		if (data->contexts[i]->tcp_sock == ssk) {
+			nr = i;
+			break;
+		}
+	}
+	subflow = data->contexts[nr];
+
+	if (!mptcp_stream_memory_free(subflow))
+		return -1;
+
+	burst = mptcp_get_burst(msk);
+	if (!burst)
+		goto out;
+
+	data->snd_burst = burst;
+	subflow->avg_pacing_rate = mptcp_get_pacing_rate(subflow, burst);
+
+out:
+	mptcp_subflow_set_scheduled(subflow, true);
+	return 0;
+}
+
+static int bpf_burst_get_retrans(const struct mptcp_sock *msk,
+				 struct mptcp_sched_data *data)
+{
+	struct sock *backup = NULL, *pick = NULL, *ret = NULL;
+	struct mptcp_subflow_context *subflow;
+	int min_stale_count = INT_MAX;
+	struct sock *ssk;
+	int i, nr = 0;
+
+	for (i = 0; i < MPTCP_SUBFLOWS_MAX; i++) {
+		if (!data->contexts[i])
+			break;
+
+		subflow = data->contexts[i];
+		ssk = mptcp_subflow_tcp_sock(subflow);
+		if (!mptcp_subflow_active(subflow))
+			continue;
+
+		/* still data outstanding at TCP level? skip this */
+		if (!mptcp_rtx_and_write_queues_empty(ssk)) {
+			mptcp_pm_subflow_chk_stale(msk, ssk);
+			min_stale_count = min(min_stale_count, subflow->stale_count);
+			continue;
+		}
+
+		if (subflow->backup) {
+			if (!backup)
+				backup = ssk;
+			continue;
+		}
+
+		if (!pick)
+			pick = ssk;
+	}
+
+	if (pick)
+		ret = pick;
+	ret = min_stale_count > 1 ? backup : NULL;
+
+	if (ret) {
+		for (i = 0; i < MPTCP_SUBFLOWS_MAX; i++) {
+			if (data->contexts[i]->tcp_sock == ret) {
+				nr = i;
+				break;
+			}
+		}
+	}
+	mptcp_subflow_set_scheduled(data->contexts[nr], true);
+	return 0;
+}
+
+int BPF_STRUCT_OPS(bpf_burst_get_subflow, const struct mptcp_sock *msk,
+		   struct mptcp_sched_data *data)
+{
+	if (data->reinject)
+		return bpf_burst_get_retrans(msk, data);
+	return bpf_burst_get_send(msk, data);
+}
+
+SEC(".struct_ops")
+struct mptcp_sched_ops burst = {
+	.init		= (void *)mptcp_sched_burst_init,
+	.release	= (void *)mptcp_sched_burst_release,
+	.data_init	= (void *)bpf_burst_data_init,
+	.get_subflow	= (void *)bpf_burst_get_subflow,
+	.name		= "bpf_burst",
+};
-- 
2.35.3


  parent reply	other threads:[~2023-05-30 13:19 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-05-30 13:17 [PATCH mptcp-next v3 00/15] save sched_data at mptcp_sock Geliang Tang
2023-05-30 13:17 ` [PATCH mptcp-next v3 01/15] Squash to "mptcp: add struct mptcp_sched_ops" Geliang Tang
2023-05-30 13:17 ` [PATCH mptcp-next v3 02/15] Squash to "mptcp: add sched in mptcp_sock" Geliang Tang
2023-05-30 13:17 ` [PATCH mptcp-next v3 03/15] Squash to "mptcp: add scheduler wrappers" Geliang Tang
2023-05-30 13:17 ` [PATCH mptcp-next v3 04/15] mptcp: add last_snd in sched_data Geliang Tang
2023-05-30 13:17 ` [PATCH mptcp-next v3 05/15] mptcp: add snd_burst " Geliang Tang
2023-05-30 13:17 ` [PATCH mptcp-next v3 06/15] mptcp: register default scheduler Geliang Tang
2023-05-30 13:17 ` [PATCH mptcp-next v3 07/15] mptcp: rename __mptcp_set_timeout for bpf_burst Geliang Tang
2023-05-30 13:17 ` [PATCH mptcp-next v3 08/15] mptcp: add two wrappers " Geliang Tang
2023-05-30 13:17 ` [PATCH mptcp-next v3 09/15] mptcp: add three helpers " Geliang Tang
2023-05-30 13:17 ` [PATCH mptcp-next v3 10/15] Squash to "bpf: Add bpf_mptcp_sched_ops" Geliang Tang
2023-05-30 13:17 ` [PATCH mptcp-next v3 11/15] Squash to "bpf: Add bpf_mptcp_sched_kfunc_set" Geliang Tang
2023-05-30 13:17 ` [PATCH mptcp-next v3 12/15] Squash to "selftests/bpf: Add mptcp sched structs" Geliang Tang
2023-05-30 13:17 ` [PATCH mptcp-next v3 13/15] Squash to "selftests/bpf: Add bpf_rr scheduler" Geliang Tang
2023-05-30 13:17 ` Geliang Tang [this message]
2023-05-30 13:17 ` [PATCH mptcp-next v3 15/15] selftests/bpf: Add bpf_burst test Geliang Tang
2023-05-30 13:50   ` selftests/bpf: Add bpf_burst test: Build Failure MPTCP CI
2023-05-30 14:46   ` selftests/bpf: Add bpf_burst test: Tests Results MPTCP CI

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=bd209c2426adc1a210b1ded5fc87f42dc833d632.1685452619.git.geliang.tang@suse.com \
    --to=geliang.tang@suse.com \
    --cc=mptcp@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.