From: Mat Martineau <mathew.j.martineau at linux.intel.com>
To: mptcp at lists.01.org
Subject: [MPTCP] Re: [MPTCP][PATCH v3 mptcp-next 8/9] mptcp: remove a list of addrs when flushing
Date: Thu, 04 Feb 2021 17:53:35 -0800 [thread overview]
Message-ID: <c4fa9252-3d92-18df-53e9-89c9adcaed26@linux.intel.com> (raw)
In-Reply-To: 8fa90a27985eac53a009842d2aa922a5ce79e0ad.1612250255.git.geliangtang@gmail.com
[-- Attachment #1: Type: text/plain, Size: 3844 bytes --]
On Tue, 2 Feb 2021, Geliang Tang wrote:
> This patch invoked mptcp_nl_remove_addrs_and_subflows to remove a list
> of addresses when the netlink flushes addresses, instead of using
> mptcp_nl_remove_subflow_and_signal_addr to remove them one by one.
>
> Since mptcp_nl_remove_subflow_and_signal_addr was dropped from
> __flush_addrs, __flush_addrs could be invoked under the locks. So
> dropped the useless free_list in mptcp_nl_cmd_flush_addrs and the unused
> parameter net in __flush_addrs.
>
> Signed-off-by: Geliang Tang <geliangtang(a)gmail.com>
> ---
> net/mptcp/pm_netlink.c | 19 +++++++++++++------
> 1 file changed, 13 insertions(+), 6 deletions(-)
>
> diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
> index e942b4ccaa76..6b6dacd0e03a 100644
> --- a/net/mptcp/pm_netlink.c
> +++ b/net/mptcp/pm_netlink.c
> @@ -1287,14 +1287,13 @@ static void mptcp_nl_remove_addrs_and_subflows(struct net *net, u8 rm_ids[])
> }
> }
>
> -static void __flush_addrs(struct net *net, struct list_head *list)
> +static void __flush_addrs(struct list_head *list)
> {
> while (!list_empty(list)) {
> struct mptcp_pm_addr_entry *cur;
>
> cur = list_entry(list->next,
> struct mptcp_pm_addr_entry, list);
> - mptcp_nl_remove_subflow_and_signal_addr(net, &cur->addr);
> list_del_rcu(&cur->list);
> mptcp_pm_free_addr_entry(cur);
> }
> @@ -1311,15 +1310,23 @@ static void __reset_counters(struct pm_nl_pernet *pernet)
> static int mptcp_nl_cmd_flush_addrs(struct sk_buff *skb, struct genl_info *info)
> {
> struct pm_nl_pernet *pernet = genl_info_pm_nl(info);
> - LIST_HEAD(free_list);
> + u8 rm_ids[MPTCP_RM_IDS_MAX] = { 0 }, i = 0;
> + struct mptcp_pm_addr_entry *entry;
> +
> + spin_lock_bh(&pernet->lock);
> + list_for_each_entry(entry, &pernet->local_addr_list, list) {
> + if (entry->addr.id && i < MPTCP_RM_IDS_MAX)
> + rm_ids[i++] = entry->addr.id;
> + }
> + spin_unlock_bh(&pernet->lock);
> + mptcp_nl_remove_addrs_and_subflows(sock_net(skb->sk), rm_ids);
>
> spin_lock_bh(&pernet->lock);
> - list_splice_init(&pernet->local_addr_list, &free_list);
> + __flush_addrs(&pernet->local_addr_list);
> __reset_counters(pernet);
> pernet->next_id = 1;
> bitmap_zero(pernet->id_bitmap, MAX_ADDR_ID + 1);
> spin_unlock_bh(&pernet->lock);
> - __flush_addrs(sock_net(skb->sk), &free_list);
With the pernet lock reacquired so many times, there's a lot of room for
the local_addr_list to change while the lock is not held. And the pernet
lock is held for a longer time.
It looks like the main idea is to change from this -
// Old code
for each announced address id:
for each msk:
close one subflow matching the announced address id
to this -
// New code
get the list of announced address ids
for each msk:
send rm_addr with list of subflow ids
close subflows matching list of subflow ids
free list of address ids directly from pernet
My suggestion is to instead keep mptcp_nl_cmd_flush_addrs() mostly
unchanged. free_list can then be used for two things at the end of the
function:
1. It can be passed to a mptcp_nl_* function that will iterate over each
msk. Use free_list instead of pernet->local_addr_list for each msk to
build the list of rm_ids, and also to remove the necessary subflows. The
pernet lock won't be needed.
2. After iterating over all the msks, deallocate the free_list (like your
modified __flush_addrs() does).
> return 0;
> }
>
> @@ -1916,7 +1923,7 @@ static void __net_exit pm_nl_exit_net(struct list_head *net_list)
> /* net is removed from namespace list, can't race with
> * other modifiers
> */
> - __flush_addrs(net, &pernet->local_addr_list);
> + __flush_addrs(&pernet->local_addr_list);
> }
> }
>
> --
> 2.29.2
--
Mat Martineau
Intel
reply other threads:[~2021-02-05 1:53 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=c4fa9252-3d92-18df-53e9-89c9adcaed26@linux.intel.com \
--to=mptcp@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox