[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CH2PR15MB3575BD179FA3B0DB95BAFA149AE40@CH2PR15MB3575.namprd15.prod.outlook.com>
Date: Thu, 20 Jun 2019 12:53:57 +0000
From: Jon Maloy <jon.maloy@...csson.com>
To: Xin Long <lucien.xin@...il.com>,
network dev <netdev@...r.kernel.org>
CC: "davem@...emloft.net" <davem@...emloft.net>,
Ying Xue <ying.xue@...driver.com>,
"tipc-discussion@...ts.sourceforge.net"
<tipc-discussion@...ts.sourceforge.net>
Subject: RE: [PATCH net] tipc: change to use register_pernet_device
Acked-by: Jon Maloy <jon.maloy@...csson.com>
> -----Original Message-----
> From: netdev-owner@...r.kernel.org <netdev-owner@...r.kernel.org> On
> Behalf Of Xin Long
> Sent: 20-Jun-19 06:39
> To: network dev <netdev@...r.kernel.org>
> Cc: davem@...emloft.net; Jon Maloy <jon.maloy@...csson.com>; Ying Xue
> <ying.xue@...driver.com>; tipc-discussion@...ts.sourceforge.net
> Subject: [PATCH net] tipc: change to use register_pernet_device
>
> This patch is to fix a dst defcnt leak, which can be reproduced by doing:.ericsson.com>
>
> # ip net a c; ip net a s; modprobe tipc
> # ip net e s ip l a n eth1 type veth peer n eth1 netns c
> # ip net e c ip l s lo up; ip net e c ip l s eth1 up
> # ip net e s ip l s lo up; ip net e s ip l s eth1 up
> # ip net e c ip a a 1.1.1.2/8 dev eth1
> # ip net e s ip a a 1.1.1.1/8 dev eth1
> # ip net e c tipc b e m udp n u1 localip 1.1.1.2
> # ip net e s tipc b e m udp n u1 localip 1.1.1.1
> # ip net d c; ip net d s; rmmod tipc
>
> and it will get stuck and keep logging the error:
>
> unregister_netdevice: waiting for lo to become free. Usage count = 1
>
> The cause is that a dst is held by the udp sock's sk_rx_dst set on udp rx path
> with udp_early_demux == 1, and this dst (eventually holding lo dev) can't be
> released as bearer's removal in tipc pernet .exit happens after lo dev's
> removal, default_device pernet .exit.
>
> "There are two distinct types of pernet_operations recognized: subsys and
> device. At creation all subsys init functions are called before device
> init functions, and at destruction all device exit functions are called
> before subsys exit function."
>
> So by calling register_pernet_device instead to register tipc_net_ops, the
> pernet .exit() will be invoked earlier than loopback dev's removal when a
> netns is being destroyed, as fou/gue does.
>
> Note that vxlan and geneve udp tunnels don't have this issue, as the udp sock
> is released in their device ndo_stop().
>
> This fix is also necessary for tipc dst_cache, which will hold dsts on tx path and
> I will introduce in my next patch.
>
> Reported-by: Li Shuang <shuali@...hat.com>
> Signed-off-by: Xin Long <lucien.xin@...il.com>
> ---
> net/tipc/core.c | 12 ++++++------
> 1 file changed, 6 insertions(+), 6 deletions(-)
>
> diff --git a/net/tipc/core.c b/net/tipc/core.c index ed536c0..c837072 100644
> --- a/net/tipc/core.c
> +++ b/net/tipc/core.c
> @@ -134,7 +134,7 @@ static int __init tipc_init(void)
> if (err)
> goto out_sysctl;
>
> - err = register_pernet_subsys(&tipc_net_ops);
> + err = register_pernet_device(&tipc_net_ops);
> if (err)
> goto out_pernet;
>
> @@ -142,7 +142,7 @@ static int __init tipc_init(void)
> if (err)
> goto out_socket;
>
> - err = register_pernet_subsys(&tipc_topsrv_net_ops);
> + err = register_pernet_device(&tipc_topsrv_net_ops);
> if (err)
> goto out_pernet_topsrv;
>
> @@ -153,11 +153,11 @@ static int __init tipc_init(void)
> pr_info("Started in single node mode\n");
> return 0;
> out_bearer:
> - unregister_pernet_subsys(&tipc_topsrv_net_ops);
> + unregister_pernet_device(&tipc_topsrv_net_ops);
> out_pernet_topsrv:
> tipc_socket_stop();
> out_socket:
> - unregister_pernet_subsys(&tipc_net_ops);
> + unregister_pernet_device(&tipc_net_ops);
> out_pernet:
> tipc_unregister_sysctl();
> out_sysctl:
> @@ -172,9 +172,9 @@ static int __init tipc_init(void) static void __exit
> tipc_exit(void) {
> tipc_bearer_cleanup();
> - unregister_pernet_subsys(&tipc_topsrv_net_ops);
> + unregister_pernet_device(&tipc_topsrv_net_ops);
> tipc_socket_stop();
> - unregister_pernet_subsys(&tipc_net_ops);
> + unregister_pernet_device(&tipc_net_ops);
> tipc_netlink_stop();
> tipc_netlink_compat_stop();
> tipc_unregister_sysctl();
> --
> 2.1.0
Powered by blists - more mailing lists