forked from mirrors/linux
		
	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: Gregory Detal <gregory.detal@gmail.com> Reviewed-by: Mat Martineau <martineau@kernel.org> Tested-by: Geliang Tang <geliang@kernel.org> Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Signed-off-by: Mat Martineau <martineau@kernel.org> Link: https://lore.kernel.org/r/20240514011335.176158-5-martineau@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
		
							parent
							
								
									ce5f6f71b0
								
							
						
					
					
						commit
						73c900aa36
					
				
					 4 changed files with 52 additions and 1 deletions
				
			
		| 
						 | 
					@ -97,6 +97,9 @@ struct mptcp_out_options {
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define MPTCP_SCHED_NAME_MAX	16
 | 
					#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
 | 
					#define MPTCP_SUBFLOWS_MAX	8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct mptcp_sched_data {
 | 
					struct mptcp_sched_data {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -133,6 +133,24 @@ static int proc_scheduler(struct ctl_table *ctl, int write,
 | 
				
			||||||
	return ret;
 | 
						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[] = {
 | 
					static struct ctl_table mptcp_sysctl_table[] = {
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		.procname = "enabled",
 | 
							.procname = "enabled",
 | 
				
			||||||
| 
						 | 
					@ -187,6 +205,12 @@ static struct ctl_table mptcp_sysctl_table[] = {
 | 
				
			||||||
		.mode = 0644,
 | 
							.mode = 0644,
 | 
				
			||||||
		.proc_handler = proc_scheduler,
 | 
							.proc_handler = proc_scheduler,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							.procname = "available_schedulers",
 | 
				
			||||||
 | 
							.maxlen	= MPTCP_SCHED_BUF_MAX,
 | 
				
			||||||
 | 
							.mode = 0644,
 | 
				
			||||||
 | 
							.proc_handler = proc_available_schedulers,
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		.procname = "close_timeout",
 | 
							.procname = "close_timeout",
 | 
				
			||||||
		.maxlen = sizeof(unsigned int),
 | 
							.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[4].data = &pernet->stale_loss_cnt;
 | 
				
			||||||
	table[5].data = &pernet->pm_type;
 | 
						table[5].data = &pernet->pm_type;
 | 
				
			||||||
	table[6].data = &pernet->scheduler;
 | 
						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,
 | 
						hdr = register_net_sysctl_sz(net, MPTCP_SYSCTL_PATH, table,
 | 
				
			||||||
				     ARRAY_SIZE(mptcp_sysctl_table));
 | 
									     ARRAY_SIZE(mptcp_sysctl_table));
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -686,6 +686,7 @@ unsigned int mptcp_stale_loss_cnt(const struct net *net);
 | 
				
			||||||
unsigned int mptcp_close_timeout(const struct sock *sk);
 | 
					unsigned int mptcp_close_timeout(const struct sock *sk);
 | 
				
			||||||
int mptcp_get_pm_type(const struct net *net);
 | 
					int mptcp_get_pm_type(const struct net *net);
 | 
				
			||||||
const char *mptcp_get_scheduler(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,
 | 
					void __mptcp_subflow_fully_established(struct mptcp_sock *msk,
 | 
				
			||||||
				       struct mptcp_subflow_context *subflow,
 | 
									       struct mptcp_subflow_context *subflow,
 | 
				
			||||||
				       const struct mptcp_options_received *mp_opt);
 | 
									       const struct mptcp_options_received *mp_opt);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -51,6 +51,28 @@ struct mptcp_sched_ops *mptcp_sched_find(const char *name)
 | 
				
			||||||
	return ret;
 | 
						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)
 | 
					int mptcp_register_scheduler(struct mptcp_sched_ops *sched)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (!sched->get_subflow)
 | 
						if (!sched->get_subflow)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue