Commit 73c900aa authored by Gregory Detal's avatar Gregory Detal Committed by Jakub Kicinski
Browse files

mptcp: add net.mptcp.available_schedulers



The sysctl lists the available schedulers that can be set using
net.mptcp.scheduler similarly to net.ipv4.tcp_available_congestion_control.

Signed-off-by: default avatarGregory Detal <gregory.detal@gmail.com>
Reviewed-by: default avatarMat Martineau <martineau@kernel.org>
Tested-by: default avatarGeliang Tang <geliang@kernel.org>
Reviewed-by: default avatarMatthieu Baerts (NGI0) <matttbe@kernel.org>
Signed-off-by: default avatarMatthieu Baerts (NGI0) <matttbe@kernel.org>
Signed-off-by: default avatarMat Martineau <martineau@kernel.org>
Link: https://lore.kernel.org/r/20240514011335.176158-5-martineau@kernel.org


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent ce5f6f71
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -97,6 +97,9 @@ struct mptcp_out_options {
};

#define MPTCP_SCHED_NAME_MAX	16
#define MPTCP_SCHED_MAX		128
#define MPTCP_SCHED_BUF_MAX	(MPTCP_SCHED_NAME_MAX * MPTCP_SCHED_MAX)

#define MPTCP_SUBFLOWS_MAX	8

struct mptcp_sched_data {
+26 −1
Original line number Diff line number Diff line
@@ -133,6 +133,24 @@ static int proc_scheduler(struct ctl_table *ctl, int write,
	return ret;
}

static int proc_available_schedulers(struct ctl_table *ctl,
				     int write, void *buffer,
				     size_t *lenp, loff_t *ppos)
{
	struct ctl_table tbl = { .maxlen = MPTCP_SCHED_BUF_MAX, };
	int ret;

	tbl.data = kmalloc(tbl.maxlen, GFP_USER);
	if (!tbl.data)
		return -ENOMEM;

	mptcp_get_available_schedulers(tbl.data, MPTCP_SCHED_BUF_MAX);
	ret = proc_dostring(&tbl, write, buffer, lenp, ppos);
	kfree(tbl.data);

	return ret;
}

static struct ctl_table mptcp_sysctl_table[] = {
	{
		.procname = "enabled",
@@ -187,6 +205,12 @@ static struct ctl_table mptcp_sysctl_table[] = {
		.mode = 0644,
		.proc_handler = proc_scheduler,
	},
	{
		.procname = "available_schedulers",
		.maxlen	= MPTCP_SCHED_BUF_MAX,
		.mode = 0644,
		.proc_handler = proc_available_schedulers,
	},
	{
		.procname = "close_timeout",
		.maxlen = sizeof(unsigned int),
@@ -214,7 +238,8 @@ static int mptcp_pernet_new_table(struct net *net, struct mptcp_pernet *pernet)
	table[4].data = &pernet->stale_loss_cnt;
	table[5].data = &pernet->pm_type;
	table[6].data = &pernet->scheduler;
	table[7].data = &pernet->close_timeout;
	/* table[7] is for available_schedulers which is read-only info */
	table[8].data = &pernet->close_timeout;

	hdr = register_net_sysctl_sz(net, MPTCP_SYSCTL_PATH, table,
				     ARRAY_SIZE(mptcp_sysctl_table));
+1 −0
Original line number Diff line number Diff line
@@ -686,6 +686,7 @@ unsigned int mptcp_stale_loss_cnt(const struct net *net);
unsigned int mptcp_close_timeout(const struct sock *sk);
int mptcp_get_pm_type(const struct net *net);
const char *mptcp_get_scheduler(const struct net *net);
void mptcp_get_available_schedulers(char *buf, size_t maxlen);
void __mptcp_subflow_fully_established(struct mptcp_sock *msk,
				       struct mptcp_subflow_context *subflow,
				       const struct mptcp_options_received *mp_opt);
+22 −0
Original line number Diff line number Diff line
@@ -51,6 +51,28 @@ struct mptcp_sched_ops *mptcp_sched_find(const char *name)
	return ret;
}

/* Build string with list of available scheduler values.
 * Similar to tcp_get_available_congestion_control()
 */
void mptcp_get_available_schedulers(char *buf, size_t maxlen)
{
	struct mptcp_sched_ops *sched;
	size_t offs = 0;

	rcu_read_lock();
	spin_lock(&mptcp_sched_list_lock);
	list_for_each_entry_rcu(sched, &mptcp_sched_list, list) {
		offs += snprintf(buf + offs, maxlen - offs,
				 "%s%s",
				 offs == 0 ? "" : " ", sched->name);

		if (WARN_ON_ONCE(offs >= maxlen))
			break;
	}
	spin_unlock(&mptcp_sched_list_lock);
	rcu_read_unlock();
}

int mptcp_register_scheduler(struct mptcp_sched_ops *sched)
{
	if (!sched->get_subflow)