diff mbox series

[mptcp-next,v5,6/8] mptcp: netlink: store lsk ref in mptcp_pm_addr_entry

Message ID 20220203072508.3072309-7-kishen.maloor@intel.com (mailing list archive)
State Superseded, archived
Headers show
Series mptcp: fixes and enhancements related to path management | expand

Checks

Context Check Description
matttbe/checkpatch success total: 0 errors, 0 warnings, 0 checks, 178 lines checked
matttbe/build fail Build error with: -Werror
matttbe/KVM_Validation__normal warning Unstable: 1 failed test(s): selftest_mptcp_join
matttbe/KVM_Validation__debug warning Unstable: 2 failed test(s): selftest_diag selftest_mptcp_join

Commit Message

Kishen Maloor Feb. 3, 2022, 7:25 a.m. UTC
This change updates struct mptcp_pm_addr_entry to store a
listening socket (lsk) reference, i.e. a pointer to a reference
counted structure containing the lsk (struct socket *) instead
of the lsk itself. Code blocks that previously operated on
the lsk in struct mptcp_pm_addr_entry have been updated to work
with the lsk ref instead, utilizing new helper functions.

Signed-off-by: Kishen Maloor <kishen.maloor@intel.com>
---
v2: fixed formatting
v3: added helper lsk_list_find_or_create(), updated
mptcp_pm_nl_create_listen_socket() to take struct net* as param
v4: call lsk_list_find() after a failed lsk_list_find_or_create()
for a chance to retrieve a recently created lsk by a simultaneous
call
v5: fixed implicit declaration error
---
 net/mptcp/pm_netlink.c | 83 +++++++++++++++++++++++++++++++-----------
 1 file changed, 62 insertions(+), 21 deletions(-)

Comments

Geliang Tang Feb. 16, 2022, 3:56 a.m. UTC | #1
Hi Kishen,

Kishen Maloor <kishen.maloor@intel.com> 于2022年2月3日周四 15:25写道:
>
> This change updates struct mptcp_pm_addr_entry to store a
> listening socket (lsk) reference, i.e. a pointer to a reference
> counted structure containing the lsk (struct socket *) instead
> of the lsk itself. Code blocks that previously operated on
> the lsk in struct mptcp_pm_addr_entry have been updated to work
> with the lsk ref instead, utilizing new helper functions.
>
> Signed-off-by: Kishen Maloor <kishen.maloor@intel.com>
> ---
> v2: fixed formatting
> v3: added helper lsk_list_find_or_create(), updated
> mptcp_pm_nl_create_listen_socket() to take struct net* as param
> v4: call lsk_list_find() after a failed lsk_list_find_or_create()
> for a chance to retrieve a recently created lsk by a simultaneous
> call
> v5: fixed implicit declaration error
> ---
>  net/mptcp/pm_netlink.c | 83 +++++++++++++++++++++++++++++++-----------
>  1 file changed, 62 insertions(+), 21 deletions(-)
>
> diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
> index 3d6251baef26..a4fb9acbba51 100644
> --- a/net/mptcp/pm_netlink.c
> +++ b/net/mptcp/pm_netlink.c
> @@ -35,7 +35,7 @@ struct mptcp_pm_addr_entry {
>         struct mptcp_addr_info  addr;
>         u8                      flags;
>         int                     ifindex;
> -       struct socket           *lsk;
> +       struct mptcp_local_lsk  *lsk_ref;
>  };
>
>  struct mptcp_pm_add_entry {
> @@ -66,6 +66,10 @@ struct pm_nl_pernet {
>  #define MPTCP_PM_ADDR_MAX      8
>  #define ADD_ADDR_RETRANS_MAX   3
>
> +static int mptcp_pm_nl_create_listen_socket(struct net *net,
> +                                           struct mptcp_pm_addr_entry *entry,
> +                                           struct socket **lsk);
> +
>  static bool addresses_equal(const struct mptcp_addr_info *a,
>                             const struct mptcp_addr_info *b, bool use_port)
>  {
> @@ -157,6 +161,33 @@ static void lsk_list_release(struct pm_nl_pernet *pernet,
>         }
>  }
>
> +static struct mptcp_local_lsk *lsk_list_find_or_create(struct net *net,
> +                                                      struct pm_nl_pernet *pernet,
> +                                                      struct mptcp_pm_addr_entry *entry,
> +                                                      int *createlsk_err)
> +{
> +       struct mptcp_local_lsk *lsk_ref;
> +       struct socket *lsk;
> +       int err;
> +
> +       lsk_ref = lsk_list_find(pernet, &entry->addr);
> +
> +       if (!lsk_ref) {
> +               err = mptcp_pm_nl_create_listen_socket(net, entry, &lsk);
> +
> +               if (createlsk_err)
> +                       *createlsk_err = err;
> +
> +               if (lsk)
> +                       lsk_ref = lsk_list_add(pernet, &entry->addr, lsk);
> +
> +               if (lsk && !lsk_ref)
> +                       sock_release(lsk);
> +       }
> +
> +       return lsk_ref;
> +}
> +
>  static bool address_zero(const struct mptcp_addr_info *addr)
>  {
>         struct mptcp_addr_info zero;
> @@ -999,8 +1030,9 @@ static int mptcp_pm_nl_append_new_local_addr(struct pm_nl_pernet *pernet,
>         return ret;
>  }
>
> -static int mptcp_pm_nl_create_listen_socket(struct sock *sk,
> -                                           struct mptcp_pm_addr_entry *entry)
> +static int mptcp_pm_nl_create_listen_socket(struct net *net,
> +                                           struct mptcp_pm_addr_entry *entry,
> +                                           struct socket **lsk)
>  {
>         int addrlen = sizeof(struct sockaddr_in);
>         struct sockaddr_storage addr;
> @@ -1009,12 +1041,12 @@ static int mptcp_pm_nl_create_listen_socket(struct sock *sk,
>         int backlog = 1024;
>         int err;
>
> -       err = sock_create_kern(sock_net(sk), entry->addr.family,
> -                              SOCK_STREAM, IPPROTO_MPTCP, &entry->lsk);
> +       err = sock_create_kern(net, entry->addr.family,
> +                              SOCK_STREAM, IPPROTO_MPTCP, lsk);
>         if (err)
>                 return err;
>
> -       msk = mptcp_sk(entry->lsk->sk);
> +       msk = mptcp_sk((*lsk)->sk);
>         if (!msk) {
>                 err = -EINVAL;
>                 goto out;
> @@ -1046,7 +1078,8 @@ static int mptcp_pm_nl_create_listen_socket(struct sock *sk,
>         return 0;
>
>  out:
> -       sock_release(entry->lsk);
> +       sock_release(*lsk);
> +       *lsk = NULL;
>         return err;
>  }
>
> @@ -1095,7 +1128,7 @@ int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct sock_common *skc)
>         entry->addr.port = 0;
>         entry->ifindex = 0;
>         entry->flags = 0;
> -       entry->lsk = NULL;
> +       entry->lsk_ref = NULL;
>         ret = mptcp_pm_nl_append_new_local_addr(pernet, entry);
>         if (ret < 0)
>                 kfree(entry);
> @@ -1304,18 +1337,25 @@ static int mptcp_nl_cmd_add_addr(struct sk_buff *skb, struct genl_info *info)
>
>         *entry = addr;
>         if (entry->addr.port) {
> -               ret = mptcp_pm_nl_create_listen_socket(skb->sk, entry);
> -               if (ret) {
> -                       GENL_SET_ERR_MSG(info, "create listen socket error");
> +               entry->lsk_ref = lsk_list_find_or_create(sock_net(skb->sk), pernet, entry, &ret);
> +
> +               if (!entry->lsk_ref)
> +                       entry->lsk_ref = lsk_list_find(pernet, &entry->addr);
> +
> +               if (!entry->lsk_ref) {
> +                       GENL_SET_ERR_MSG(info, "can't create/allocate lsk");
>                         kfree(entry);
> +                       ret = (ret == 0) ? -ENOMEM : ret;
>                         return ret;
>                 }
>         }
> +

Blank lines aren't necessary here,

>         ret = mptcp_pm_nl_append_new_local_addr(pernet, entry);
> +

and here.

Thanks,

Geliang
SUSE

>         if (ret < 0) {
>                 GENL_SET_ERR_MSG(info, "too many addresses or duplicate one");
> -               if (entry->lsk)
> -                       sock_release(entry->lsk);
> +               if (entry->lsk_ref)
> +                       lsk_list_release(pernet, entry->lsk_ref);
>                 kfree(entry);
>                 return ret;
>         }
> @@ -1418,10 +1458,11 @@ static int mptcp_nl_remove_subflow_and_signal_addr(struct net *net,
>  }
>
>  /* caller must ensure the RCU grace period is already elapsed */
> -static void __mptcp_pm_release_addr_entry(struct mptcp_pm_addr_entry *entry)
> +static void __mptcp_pm_release_addr_entry(struct pm_nl_pernet *pernet,
> +                                         struct mptcp_pm_addr_entry *entry)
>  {
> -       if (entry->lsk)
> -               sock_release(entry->lsk);
> +       if (entry->lsk_ref)
> +               lsk_list_release(pernet, entry->lsk_ref);
>         kfree(entry);
>  }
>
> @@ -1503,7 +1544,7 @@ static int mptcp_nl_cmd_del_addr(struct sk_buff *skb, struct genl_info *info)
>
>         mptcp_nl_remove_subflow_and_signal_addr(sock_net(skb->sk), &entry->addr);
>         synchronize_rcu();
> -       __mptcp_pm_release_addr_entry(entry);
> +       __mptcp_pm_release_addr_entry(pernet, entry);
>
>         return ret;
>  }
> @@ -1559,7 +1600,7 @@ static void mptcp_nl_remove_addrs_list(struct net *net,
>  }
>
>  /* caller must ensure the RCU grace period is already elapsed */
> -static void __flush_addrs(struct list_head *list)
> +static void __flush_addrs(struct pm_nl_pernet *pernet, struct list_head *list)
>  {
>         while (!list_empty(list)) {
>                 struct mptcp_pm_addr_entry *cur;
> @@ -1567,7 +1608,7 @@ static void __flush_addrs(struct list_head *list)
>                 cur = list_entry(list->next,
>                                  struct mptcp_pm_addr_entry, list);
>                 list_del_rcu(&cur->list);
> -               __mptcp_pm_release_addr_entry(cur);
> +               __mptcp_pm_release_addr_entry(pernet, cur);
>         }
>  }
>
> @@ -1592,7 +1633,7 @@ static int mptcp_nl_cmd_flush_addrs(struct sk_buff *skb, struct genl_info *info)
>         spin_unlock_bh(&pernet->lock);
>         mptcp_nl_remove_addrs_list(sock_net(skb->sk), &free_list);
>         synchronize_rcu();
> -       __flush_addrs(&free_list);
> +       __flush_addrs(pernet, &free_list);
>         return 0;
>  }
>
> @@ -2242,7 +2283,7 @@ static void __net_exit pm_nl_exit_net(struct list_head *net_list)
>                  * other modifiers, also netns core already waited for a
>                  * RCU grace period.
>                  */
> -               __flush_addrs(&pernet->local_addr_list);
> +               __flush_addrs(pernet, &pernet->local_addr_list);
>         }
>  }
>
> --
> 2.31.1
>
>
diff mbox series

Patch

diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
index 3d6251baef26..a4fb9acbba51 100644
--- a/net/mptcp/pm_netlink.c
+++ b/net/mptcp/pm_netlink.c
@@ -35,7 +35,7 @@  struct mptcp_pm_addr_entry {
 	struct mptcp_addr_info	addr;
 	u8			flags;
 	int			ifindex;
-	struct socket		*lsk;
+	struct mptcp_local_lsk	*lsk_ref;
 };
 
 struct mptcp_pm_add_entry {
@@ -66,6 +66,10 @@  struct pm_nl_pernet {
 #define MPTCP_PM_ADDR_MAX	8
 #define ADD_ADDR_RETRANS_MAX	3
 
+static int mptcp_pm_nl_create_listen_socket(struct net *net,
+					    struct mptcp_pm_addr_entry *entry,
+					    struct socket **lsk);
+
 static bool addresses_equal(const struct mptcp_addr_info *a,
 			    const struct mptcp_addr_info *b, bool use_port)
 {
@@ -157,6 +161,33 @@  static void lsk_list_release(struct pm_nl_pernet *pernet,
 	}
 }
 
+static struct mptcp_local_lsk *lsk_list_find_or_create(struct net *net,
+						       struct pm_nl_pernet *pernet,
+						       struct mptcp_pm_addr_entry *entry,
+						       int *createlsk_err)
+{
+	struct mptcp_local_lsk *lsk_ref;
+	struct socket *lsk;
+	int err;
+
+	lsk_ref = lsk_list_find(pernet, &entry->addr);
+
+	if (!lsk_ref) {
+		err = mptcp_pm_nl_create_listen_socket(net, entry, &lsk);
+
+		if (createlsk_err)
+			*createlsk_err = err;
+
+		if (lsk)
+			lsk_ref = lsk_list_add(pernet, &entry->addr, lsk);
+
+		if (lsk && !lsk_ref)
+			sock_release(lsk);
+	}
+
+	return lsk_ref;
+}
+
 static bool address_zero(const struct mptcp_addr_info *addr)
 {
 	struct mptcp_addr_info zero;
@@ -999,8 +1030,9 @@  static int mptcp_pm_nl_append_new_local_addr(struct pm_nl_pernet *pernet,
 	return ret;
 }
 
-static int mptcp_pm_nl_create_listen_socket(struct sock *sk,
-					    struct mptcp_pm_addr_entry *entry)
+static int mptcp_pm_nl_create_listen_socket(struct net *net,
+					    struct mptcp_pm_addr_entry *entry,
+					    struct socket **lsk)
 {
 	int addrlen = sizeof(struct sockaddr_in);
 	struct sockaddr_storage addr;
@@ -1009,12 +1041,12 @@  static int mptcp_pm_nl_create_listen_socket(struct sock *sk,
 	int backlog = 1024;
 	int err;
 
-	err = sock_create_kern(sock_net(sk), entry->addr.family,
-			       SOCK_STREAM, IPPROTO_MPTCP, &entry->lsk);
+	err = sock_create_kern(net, entry->addr.family,
+			       SOCK_STREAM, IPPROTO_MPTCP, lsk);
 	if (err)
 		return err;
 
-	msk = mptcp_sk(entry->lsk->sk);
+	msk = mptcp_sk((*lsk)->sk);
 	if (!msk) {
 		err = -EINVAL;
 		goto out;
@@ -1046,7 +1078,8 @@  static int mptcp_pm_nl_create_listen_socket(struct sock *sk,
 	return 0;
 
 out:
-	sock_release(entry->lsk);
+	sock_release(*lsk);
+	*lsk = NULL;
 	return err;
 }
 
@@ -1095,7 +1128,7 @@  int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct sock_common *skc)
 	entry->addr.port = 0;
 	entry->ifindex = 0;
 	entry->flags = 0;
-	entry->lsk = NULL;
+	entry->lsk_ref = NULL;
 	ret = mptcp_pm_nl_append_new_local_addr(pernet, entry);
 	if (ret < 0)
 		kfree(entry);
@@ -1304,18 +1337,25 @@  static int mptcp_nl_cmd_add_addr(struct sk_buff *skb, struct genl_info *info)
 
 	*entry = addr;
 	if (entry->addr.port) {
-		ret = mptcp_pm_nl_create_listen_socket(skb->sk, entry);
-		if (ret) {
-			GENL_SET_ERR_MSG(info, "create listen socket error");
+		entry->lsk_ref = lsk_list_find_or_create(sock_net(skb->sk), pernet, entry, &ret);
+
+		if (!entry->lsk_ref)
+			entry->lsk_ref = lsk_list_find(pernet, &entry->addr);
+
+		if (!entry->lsk_ref) {
+			GENL_SET_ERR_MSG(info, "can't create/allocate lsk");
 			kfree(entry);
+			ret = (ret == 0) ? -ENOMEM : ret;
 			return ret;
 		}
 	}
+
 	ret = mptcp_pm_nl_append_new_local_addr(pernet, entry);
+
 	if (ret < 0) {
 		GENL_SET_ERR_MSG(info, "too many addresses or duplicate one");
-		if (entry->lsk)
-			sock_release(entry->lsk);
+		if (entry->lsk_ref)
+			lsk_list_release(pernet, entry->lsk_ref);
 		kfree(entry);
 		return ret;
 	}
@@ -1418,10 +1458,11 @@  static int mptcp_nl_remove_subflow_and_signal_addr(struct net *net,
 }
 
 /* caller must ensure the RCU grace period is already elapsed */
-static void __mptcp_pm_release_addr_entry(struct mptcp_pm_addr_entry *entry)
+static void __mptcp_pm_release_addr_entry(struct pm_nl_pernet *pernet,
+					  struct mptcp_pm_addr_entry *entry)
 {
-	if (entry->lsk)
-		sock_release(entry->lsk);
+	if (entry->lsk_ref)
+		lsk_list_release(pernet, entry->lsk_ref);
 	kfree(entry);
 }
 
@@ -1503,7 +1544,7 @@  static int mptcp_nl_cmd_del_addr(struct sk_buff *skb, struct genl_info *info)
 
 	mptcp_nl_remove_subflow_and_signal_addr(sock_net(skb->sk), &entry->addr);
 	synchronize_rcu();
-	__mptcp_pm_release_addr_entry(entry);
+	__mptcp_pm_release_addr_entry(pernet, entry);
 
 	return ret;
 }
@@ -1559,7 +1600,7 @@  static void mptcp_nl_remove_addrs_list(struct net *net,
 }
 
 /* caller must ensure the RCU grace period is already elapsed */
-static void __flush_addrs(struct list_head *list)
+static void __flush_addrs(struct pm_nl_pernet *pernet, struct list_head *list)
 {
 	while (!list_empty(list)) {
 		struct mptcp_pm_addr_entry *cur;
@@ -1567,7 +1608,7 @@  static void __flush_addrs(struct list_head *list)
 		cur = list_entry(list->next,
 				 struct mptcp_pm_addr_entry, list);
 		list_del_rcu(&cur->list);
-		__mptcp_pm_release_addr_entry(cur);
+		__mptcp_pm_release_addr_entry(pernet, cur);
 	}
 }
 
@@ -1592,7 +1633,7 @@  static int mptcp_nl_cmd_flush_addrs(struct sk_buff *skb, struct genl_info *info)
 	spin_unlock_bh(&pernet->lock);
 	mptcp_nl_remove_addrs_list(sock_net(skb->sk), &free_list);
 	synchronize_rcu();
-	__flush_addrs(&free_list);
+	__flush_addrs(pernet, &free_list);
 	return 0;
 }
 
@@ -2242,7 +2283,7 @@  static void __net_exit pm_nl_exit_net(struct list_head *net_list)
 		 * other modifiers, also netns core already waited for a
 		 * RCU grace period.
 		 */
-		__flush_addrs(&pernet->local_addr_list);
+		__flush_addrs(pernet, &pernet->local_addr_list);
 	}
 }