Commit a914e586 authored by Geliang Tang's avatar Geliang Tang Committed by Jakub Kicinski

mptcp: drop *_max fields in mptcp_pm_data

This patch drops the per-msk values add_addr_signal_max,
add_addr_accept_max, local_addr_max and subflows_max fields in struct
mptcp_pm_data, uses the pernet *_max values instead. And adds four new
helpers to get the pernet *_max values separately.
Co-developed-by: default avatarMatthieu Baerts <matthieu.baerts@tessares.net>
Signed-off-by: default avatarMatthieu Baerts <matthieu.baerts@tessares.net>
Signed-off-by: default avatarGeliang Tang <geliangtang@gmail.com>
Signed-off-by: default avatarMat Martineau <mathew.j.martineau@linux.intel.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 72603d20
...@@ -128,10 +128,10 @@ static void mptcp_diag_get_info(struct sock *sk, struct inet_diag_msg *r, ...@@ -128,10 +128,10 @@ static void mptcp_diag_get_info(struct sock *sk, struct inet_diag_msg *r,
info->mptcpi_subflows = READ_ONCE(msk->pm.subflows); info->mptcpi_subflows = READ_ONCE(msk->pm.subflows);
info->mptcpi_add_addr_signal = READ_ONCE(msk->pm.add_addr_signaled); info->mptcpi_add_addr_signal = READ_ONCE(msk->pm.add_addr_signaled);
info->mptcpi_add_addr_accepted = READ_ONCE(msk->pm.add_addr_accepted); info->mptcpi_add_addr_accepted = READ_ONCE(msk->pm.add_addr_accepted);
info->mptcpi_subflows_max = READ_ONCE(msk->pm.subflows_max); info->mptcpi_subflows_max = mptcp_pm_get_subflows_max(msk);
val = READ_ONCE(msk->pm.add_addr_signal_max); val = mptcp_pm_get_add_addr_signal_max(msk);
info->mptcpi_add_addr_signal_max = val; info->mptcpi_add_addr_signal_max = val;
val = READ_ONCE(msk->pm.add_addr_accept_max); val = mptcp_pm_get_add_addr_accept_max(msk);
info->mptcpi_add_addr_accepted_max = val; info->mptcpi_add_addr_accepted_max = val;
if (test_bit(MPTCP_FALLBACK_DONE, &msk->flags)) if (test_bit(MPTCP_FALLBACK_DONE, &msk->flags))
flags |= MPTCP_INFO_FLAG_FALLBACK; flags |= MPTCP_INFO_FLAG_FALLBACK;
......
...@@ -78,10 +78,13 @@ void mptcp_pm_new_connection(struct mptcp_sock *msk, int server_side) ...@@ -78,10 +78,13 @@ void mptcp_pm_new_connection(struct mptcp_sock *msk, int server_side)
bool mptcp_pm_allow_new_subflow(struct mptcp_sock *msk) bool mptcp_pm_allow_new_subflow(struct mptcp_sock *msk)
{ {
struct mptcp_pm_data *pm = &msk->pm; struct mptcp_pm_data *pm = &msk->pm;
unsigned int subflows_max;
int ret = 0; int ret = 0;
subflows_max = mptcp_pm_get_subflows_max(msk);
pr_debug("msk=%p subflows=%d max=%d allow=%d", msk, pm->subflows, pr_debug("msk=%p subflows=%d max=%d allow=%d", msk, pm->subflows,
pm->subflows_max, READ_ONCE(pm->accept_subflow)); subflows_max, READ_ONCE(pm->accept_subflow));
/* try to avoid acquiring the lock below */ /* try to avoid acquiring the lock below */
if (!READ_ONCE(pm->accept_subflow)) if (!READ_ONCE(pm->accept_subflow))
...@@ -89,8 +92,8 @@ bool mptcp_pm_allow_new_subflow(struct mptcp_sock *msk) ...@@ -89,8 +92,8 @@ bool mptcp_pm_allow_new_subflow(struct mptcp_sock *msk)
spin_lock_bh(&pm->lock); spin_lock_bh(&pm->lock);
if (READ_ONCE(pm->accept_subflow)) { if (READ_ONCE(pm->accept_subflow)) {
ret = pm->subflows < pm->subflows_max; ret = pm->subflows < subflows_max;
if (ret && ++pm->subflows == pm->subflows_max) if (ret && ++pm->subflows == subflows_max)
WRITE_ONCE(pm->accept_subflow, false); WRITE_ONCE(pm->accept_subflow, false);
} }
spin_unlock_bh(&pm->lock); spin_unlock_bh(&pm->lock);
......
...@@ -196,11 +196,46 @@ select_signal_address(struct pm_nl_pernet *pernet, unsigned int pos) ...@@ -196,11 +196,46 @@ select_signal_address(struct pm_nl_pernet *pernet, unsigned int pos)
return ret; return ret;
} }
unsigned int mptcp_pm_get_add_addr_signal_max(struct mptcp_sock *msk)
{
struct pm_nl_pernet *pernet;
pernet = net_generic(sock_net((struct sock *)msk), pm_nl_pernet_id);
return READ_ONCE(pernet->add_addr_signal_max);
}
EXPORT_SYMBOL_GPL(mptcp_pm_get_add_addr_signal_max);
unsigned int mptcp_pm_get_add_addr_accept_max(struct mptcp_sock *msk)
{
struct pm_nl_pernet *pernet;
pernet = net_generic(sock_net((struct sock *)msk), pm_nl_pernet_id);
return READ_ONCE(pernet->add_addr_accept_max);
}
EXPORT_SYMBOL_GPL(mptcp_pm_get_add_addr_accept_max);
unsigned int mptcp_pm_get_subflows_max(struct mptcp_sock *msk)
{
struct pm_nl_pernet *pernet;
pernet = net_generic(sock_net((struct sock *)msk), pm_nl_pernet_id);
return READ_ONCE(pernet->subflows_max);
}
EXPORT_SYMBOL_GPL(mptcp_pm_get_subflows_max);
static unsigned int mptcp_pm_get_local_addr_max(struct mptcp_sock *msk)
{
struct pm_nl_pernet *pernet;
pernet = net_generic(sock_net((struct sock *)msk), pm_nl_pernet_id);
return READ_ONCE(pernet->local_addr_max);
}
static void check_work_pending(struct mptcp_sock *msk) static void check_work_pending(struct mptcp_sock *msk)
{ {
if (msk->pm.add_addr_signaled == msk->pm.add_addr_signal_max && if (msk->pm.add_addr_signaled == mptcp_pm_get_add_addr_signal_max(msk) &&
(msk->pm.local_addr_used == msk->pm.local_addr_max || (msk->pm.local_addr_used == mptcp_pm_get_local_addr_max(msk) ||
msk->pm.subflows == msk->pm.subflows_max)) msk->pm.subflows == mptcp_pm_get_subflows_max(msk)))
WRITE_ONCE(msk->pm.work_pending, false); WRITE_ONCE(msk->pm.work_pending, false);
} }
...@@ -327,17 +362,24 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk) ...@@ -327,17 +362,24 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
{ {
struct sock *sk = (struct sock *)msk; struct sock *sk = (struct sock *)msk;
struct mptcp_pm_addr_entry *local; struct mptcp_pm_addr_entry *local;
unsigned int add_addr_signal_max;
unsigned int local_addr_max;
struct pm_nl_pernet *pernet; struct pm_nl_pernet *pernet;
unsigned int subflows_max;
pernet = net_generic(sock_net(sk), pm_nl_pernet_id); pernet = net_generic(sock_net(sk), pm_nl_pernet_id);
add_addr_signal_max = mptcp_pm_get_add_addr_signal_max(msk);
local_addr_max = mptcp_pm_get_local_addr_max(msk);
subflows_max = mptcp_pm_get_subflows_max(msk);
pr_debug("local %d:%d signal %d:%d subflows %d:%d\n", pr_debug("local %d:%d signal %d:%d subflows %d:%d\n",
msk->pm.local_addr_used, msk->pm.local_addr_max, msk->pm.local_addr_used, local_addr_max,
msk->pm.add_addr_signaled, msk->pm.add_addr_signal_max, msk->pm.add_addr_signaled, add_addr_signal_max,
msk->pm.subflows, msk->pm.subflows_max); msk->pm.subflows, subflows_max);
/* check first for announce */ /* check first for announce */
if (msk->pm.add_addr_signaled < msk->pm.add_addr_signal_max) { if (msk->pm.add_addr_signaled < add_addr_signal_max) {
local = select_signal_address(pernet, local = select_signal_address(pernet,
msk->pm.add_addr_signaled); msk->pm.add_addr_signaled);
...@@ -349,15 +391,15 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk) ...@@ -349,15 +391,15 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
} }
} else { } else {
/* pick failed, avoid fourther attempts later */ /* pick failed, avoid fourther attempts later */
msk->pm.local_addr_used = msk->pm.add_addr_signal_max; msk->pm.local_addr_used = add_addr_signal_max;
} }
check_work_pending(msk); check_work_pending(msk);
} }
/* check if should create a new subflow */ /* check if should create a new subflow */
if (msk->pm.local_addr_used < msk->pm.local_addr_max && if (msk->pm.local_addr_used < local_addr_max &&
msk->pm.subflows < msk->pm.subflows_max) { msk->pm.subflows < subflows_max) {
local = select_local_address(pernet, msk); local = select_local_address(pernet, msk);
if (local) { if (local) {
struct mptcp_addr_info remote = { 0 }; struct mptcp_addr_info remote = { 0 };
...@@ -373,7 +415,7 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk) ...@@ -373,7 +415,7 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
} }
/* lookup failed, avoid fourther attempts later */ /* lookup failed, avoid fourther attempts later */
msk->pm.local_addr_used = msk->pm.local_addr_max; msk->pm.local_addr_used = local_addr_max;
check_work_pending(msk); check_work_pending(msk);
} }
} }
...@@ -391,17 +433,22 @@ void mptcp_pm_nl_subflow_established(struct mptcp_sock *msk) ...@@ -391,17 +433,22 @@ void mptcp_pm_nl_subflow_established(struct mptcp_sock *msk)
void mptcp_pm_nl_add_addr_received(struct mptcp_sock *msk) void mptcp_pm_nl_add_addr_received(struct mptcp_sock *msk)
{ {
struct sock *sk = (struct sock *)msk; struct sock *sk = (struct sock *)msk;
unsigned int add_addr_accept_max;
struct mptcp_addr_info remote; struct mptcp_addr_info remote;
struct mptcp_addr_info local; struct mptcp_addr_info local;
unsigned int subflows_max;
bool use_port = false; bool use_port = false;
add_addr_accept_max = mptcp_pm_get_add_addr_accept_max(msk);
subflows_max = mptcp_pm_get_subflows_max(msk);
pr_debug("accepted %d:%d remote family %d", pr_debug("accepted %d:%d remote family %d",
msk->pm.add_addr_accepted, msk->pm.add_addr_accept_max, msk->pm.add_addr_accepted, add_addr_accept_max,
msk->pm.remote.family); msk->pm.remote.family);
msk->pm.add_addr_accepted++; msk->pm.add_addr_accepted++;
msk->pm.subflows++; msk->pm.subflows++;
if (msk->pm.add_addr_accepted >= msk->pm.add_addr_accept_max || if (msk->pm.add_addr_accepted >= add_addr_accept_max ||
msk->pm.subflows >= msk->pm.subflows_max) msk->pm.subflows >= subflows_max)
WRITE_ONCE(msk->pm.accept_addr, false); WRITE_ONCE(msk->pm.accept_addr, false);
/* connect to the specified remote address, using whatever /* connect to the specified remote address, using whatever
...@@ -687,19 +734,12 @@ int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct sock_common *skc) ...@@ -687,19 +734,12 @@ int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct sock_common *skc)
void mptcp_pm_nl_data_init(struct mptcp_sock *msk) void mptcp_pm_nl_data_init(struct mptcp_sock *msk)
{ {
struct mptcp_pm_data *pm = &msk->pm; struct mptcp_pm_data *pm = &msk->pm;
struct pm_nl_pernet *pernet;
bool subflows; bool subflows;
pernet = net_generic(sock_net((struct sock *)msk), pm_nl_pernet_id); subflows = !!mptcp_pm_get_subflows_max(msk);
WRITE_ONCE(pm->work_pending, (!!mptcp_pm_get_local_addr_max(msk) && subflows) ||
pm->add_addr_signal_max = READ_ONCE(pernet->add_addr_signal_max); !!mptcp_pm_get_add_addr_signal_max(msk));
pm->add_addr_accept_max = READ_ONCE(pernet->add_addr_accept_max); WRITE_ONCE(pm->accept_addr, !!mptcp_pm_get_add_addr_accept_max(msk) && subflows);
pm->local_addr_max = READ_ONCE(pernet->local_addr_max);
pm->subflows_max = READ_ONCE(pernet->subflows_max);
subflows = !!pm->subflows_max;
WRITE_ONCE(pm->work_pending, (!!pm->local_addr_max && subflows) ||
!!pm->add_addr_signal_max);
WRITE_ONCE(pm->accept_addr, !!pm->add_addr_accept_max && subflows);
WRITE_ONCE(pm->accept_subflow, subflows); WRITE_ONCE(pm->accept_subflow, subflows);
} }
......
...@@ -203,10 +203,6 @@ struct mptcp_pm_data { ...@@ -203,10 +203,6 @@ struct mptcp_pm_data {
u8 add_addr_accepted; u8 add_addr_accepted;
u8 local_addr_used; u8 local_addr_used;
u8 subflows; u8 subflows;
u8 add_addr_signal_max;
u8 add_addr_accept_max;
u8 local_addr_max;
u8 subflows_max;
u8 status; u8 status;
u8 rm_id; u8 rm_id;
}; };
...@@ -714,6 +710,9 @@ void mptcp_pm_nl_add_addr_send_ack(struct mptcp_sock *msk); ...@@ -714,6 +710,9 @@ void mptcp_pm_nl_add_addr_send_ack(struct mptcp_sock *msk);
void mptcp_pm_nl_rm_addr_received(struct mptcp_sock *msk); void mptcp_pm_nl_rm_addr_received(struct mptcp_sock *msk);
void mptcp_pm_nl_rm_subflow_received(struct mptcp_sock *msk, u8 rm_id); void mptcp_pm_nl_rm_subflow_received(struct mptcp_sock *msk, u8 rm_id);
int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct sock_common *skc); int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct sock_common *skc);
unsigned int mptcp_pm_get_add_addr_signal_max(struct mptcp_sock *msk);
unsigned int mptcp_pm_get_add_addr_accept_max(struct mptcp_sock *msk);
unsigned int mptcp_pm_get_subflows_max(struct mptcp_sock *msk);
static inline struct mptcp_ext *mptcp_get_ext(struct sk_buff *skb) static inline struct mptcp_ext *mptcp_get_ext(struct sk_buff *skb)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment