aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeliang Tang <geliang.tang@linux.dev>2023-12-08 18:14:38 +0800
committerGeliang Tang <tanggeliang@kylinos.cn>2024-04-22 10:56:53 +0800
commitf503299453580131805f19a03915cbfc491e5554 (patch)
tree800effa4a2372012b87d63cfb70bfb5710ca1af8
parente9d21ca9961aed0225db86c727d85048975131c9 (diff)
downloadmptcp_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.c33
-rw-r--r--net/mptcp/protocol.h2
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 {