mptcp: sched: split get_subflow interface into two

get_retrans() interface of the burst packet scheduler invokes a sleeping
function mptcp_pm_subflow_chk_stale(), which calls __lock_sock_fast().
So get_retrans() interface should be set with BPF_F_SLEEPABLE flag in
BPF. But get_send() interface of this scheduler can't be set with
BPF_F_SLEEPABLE flag since it's invoked in ack_update_msk() under mptcp
data lock.

So this patch has to split get_subflow() interface of packet scheduer into
two interfaces: get_send() and get_retrans(). Then we can set get_retrans()
interface alone with BPF_F_SLEEPABLE flag.

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
Reviewed-by: Mat Martineau <martineau@kernel.org>
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Link: https://patch.msgid.link/20250221-net-next-mptcp-pm-misc-cleanup-3-v1-8-2b70ab1cee79@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Geliang Tang 2025-02-21 16:44:01 +01:00 committed by Jakub Kicinski
parent 7720790fd5
commit 9771a96a7a
2 changed files with 27 additions and 13 deletions

View File

@ -103,13 +103,14 @@ struct mptcp_out_options {
#define MPTCP_SUBFLOWS_MAX 8
struct mptcp_sched_data {
bool reinject;
u8 subflows;
struct mptcp_subflow_context *contexts[MPTCP_SUBFLOWS_MAX];
};
struct mptcp_sched_ops {
int (*get_subflow)(struct mptcp_sock *msk,
int (*get_send)(struct mptcp_sock *msk,
struct mptcp_sched_data *data);
int (*get_retrans)(struct mptcp_sock *msk,
struct mptcp_sched_data *data);
char name[MPTCP_SCHED_NAME_MAX];

View File

@ -16,13 +16,25 @@
static DEFINE_SPINLOCK(mptcp_sched_list_lock);
static LIST_HEAD(mptcp_sched_list);
static int mptcp_sched_default_get_subflow(struct mptcp_sock *msk,
static int mptcp_sched_default_get_send(struct mptcp_sock *msk,
struct mptcp_sched_data *data)
{
struct sock *ssk;
ssk = mptcp_subflow_get_send(msk);
if (!ssk)
return -EINVAL;
mptcp_subflow_set_scheduled(mptcp_subflow_ctx(ssk), true);
return 0;
}
static int mptcp_sched_default_get_retrans(struct mptcp_sock *msk,
struct mptcp_sched_data *data)
{
struct sock *ssk;
ssk = data->reinject ? mptcp_subflow_get_retrans(msk) :
mptcp_subflow_get_send(msk);
ssk = mptcp_subflow_get_retrans(msk);
if (!ssk)
return -EINVAL;
@ -31,7 +43,8 @@ static int mptcp_sched_default_get_subflow(struct mptcp_sock *msk,
}
static struct mptcp_sched_ops mptcp_sched_default = {
.get_subflow = mptcp_sched_default_get_subflow,
.get_send = mptcp_sched_default_get_send,
.get_retrans = mptcp_sched_default_get_retrans,
.name = "default",
.owner = THIS_MODULE,
};
@ -73,7 +86,7 @@ void mptcp_get_available_schedulers(char *buf, size_t maxlen)
int mptcp_register_scheduler(struct mptcp_sched_ops *sched)
{
if (!sched->get_subflow)
if (!sched->get_send)
return -EINVAL;
spin_lock(&mptcp_sched_list_lock);
@ -164,10 +177,9 @@ int mptcp_sched_get_send(struct mptcp_sock *msk)
return 0;
}
data.reinject = false;
if (msk->sched == &mptcp_sched_default || !msk->sched)
return mptcp_sched_default_get_subflow(msk, &data);
return msk->sched->get_subflow(msk, &data);
return mptcp_sched_default_get_send(msk, &data);
return msk->sched->get_send(msk, &data);
}
int mptcp_sched_get_retrans(struct mptcp_sock *msk)
@ -186,8 +198,9 @@ int mptcp_sched_get_retrans(struct mptcp_sock *msk)
return 0;
}
data.reinject = true;
if (msk->sched == &mptcp_sched_default || !msk->sched)
return mptcp_sched_default_get_subflow(msk, &data);
return msk->sched->get_subflow(msk, &data);
return mptcp_sched_default_get_retrans(msk, &data);
if (msk->sched->get_retrans)
return msk->sched->get_retrans(msk, &data);
return msk->sched->get_send(msk, &data);
}