diff options
author | Geliang Tang <geliang.tang@linux.dev> | 2023-12-08 18:14:38 +0800 |
---|---|---|
committer | Geliang Tang <tanggeliang@kylinos.cn> | 2024-04-22 10:56:53 +0800 |
commit | f503299453580131805f19a03915cbfc491e5554 (patch) | |
tree | 800effa4a2372012b87d63cfb70bfb5710ca1af8 | |
parent | e9d21ca9961aed0225db86c727d85048975131c9 (diff) | |
download | mptcp_net-next-f503299453580131805f19a03915cbfc491e5554.tar.gz |
mptcp: add userspace pm addr entry refcount
This patch adds the refcount of addree entry in userspace PM. Add a new
counter 'refcnt' in struct mptcp_pm_addr_entry, initiated to 1.
Increase this counter when an address is announced or a subflow is created
in mptcp_pm_nl_announce_doit() and mptcp_pm_nl_subflow_create_doit(). And
decrease it when an address is removed or a subflow is closed in
mptcp_pm_nl_remove_doit() and mptcp_userspace_pm_delete_local_addr(). If
the counter reaches to 1, free this entry.
Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/403
Fixes: 24430f8bf516 ("mptcp: add address into userspace pm list")
Signed-off-by: Geliang Tang <geliang.tang@linux.dev>
-rw-r--r-- | net/mptcp/pm_userspace.c | 33 | ||||
-rw-r--r-- | net/mptcp/protocol.h | 2 |
2 files changed, 25 insertions, 10 deletions
diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c index 5c46f1f61b163e..9c2feb3883b381 100644 --- a/net/mptcp/pm_userspace.c +++ b/net/mptcp/pm_userspace.c @@ -63,6 +63,7 @@ static int mptcp_userspace_pm_append_new_local_addr(struct mptcp_sock *msk, 1); list_add_tail_rcu(&e->list, &msk->pm.userspace_pm_local_addr_list); msk->pm.local_addr_used++; + refcount_set(&e->refcnt, 1); ret = e->addr.id; append_err: @@ -95,12 +96,11 @@ static int mptcp_userspace_pm_delete_local_addr(struct mptcp_sock *msk, entry = mptcp_userspace_pm_get_entry(msk, &addr->addr); if (entry) { - /* TODO: a refcount is needed because the entry can - * be used multiple times (e.g. fullmesh mode). - */ - list_del_rcu(&entry->list); - kfree(entry); - msk->pm.local_addr_used--; + if (!refcount_dec_not_one(&entry->refcnt)) { + list_del_rcu(&entry->list); + kfree(entry); + msk->pm.local_addr_used--; + } return 0; } @@ -212,6 +212,11 @@ int mptcp_pm_nl_announce_doit(struct sk_buff *skb, struct genl_info *info) spin_lock_bh(&msk->pm.lock); if (mptcp_pm_alloc_anno_list(msk, &addr_val.addr)) { + struct mptcp_pm_addr_entry *entry; + + entry = mptcp_userspace_pm_get_entry(msk, &addr_val.addr); + if (entry && !refcount_inc_not_zero(&entry->refcnt)) + pr_debug("userspace pm uninitialized entry"); msk->pm.add_addr_signaled++; mptcp_pm_announce_addr(msk, &addr_val.addr, false); mptcp_pm_nl_addr_send_ack(msk); @@ -317,8 +322,10 @@ int mptcp_pm_nl_remove_doit(struct sk_buff *skb, struct genl_info *info) mptcp_pm_remove_addrs(msk, &free_list); - list_del_rcu(&match->list); - kfree(match); + if (!refcount_dec_not_one(&match->refcnt)) { + list_del_rcu(&match->list); + kfree(match); + } release_sock(sk); @@ -402,10 +409,16 @@ int mptcp_pm_nl_subflow_create_doit(struct sk_buff *skb, struct genl_info *info) release_sock(sk); spin_lock_bh(&msk->pm.lock); - if (err) + if (err) { mptcp_userspace_pm_delete_local_addr(msk, &local); - else + } else { + struct mptcp_pm_addr_entry *entry; + + entry = mptcp_userspace_pm_get_entry(msk, &local.addr); + if (entry && !refcount_inc_not_zero(&entry->refcnt)) + pr_debug("userspace pm uninitialized entry"); msk->pm.subflows++; + } spin_unlock_bh(&msk->pm.lock); create_err: diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index 7ee0f400bd57c8..2a27c044732db1 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -8,6 +8,7 @@ #define __MPTCP_PROTOCOL_H #include <linux/random.h> +#include <linux/refcount.h> #include <net/tcp.h> #include <net/inet_connection_sock.h> #include <uapi/linux/mptcp.h> @@ -243,6 +244,7 @@ struct mptcp_pm_addr_entry { u8 flags; int ifindex; struct socket *lsk; + refcount_t refcnt; }; struct mptcp_data_frag { |