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 |
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 |
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 --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); } }
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(-)