Acked-by: Jon Maloy <[email protected]> > -----Original Message----- > From: [email protected] <[email protected]> On > Behalf Of Xin Long > Sent: 20-Jun-19 06:39 > To: network dev <[email protected]> > Cc: [email protected]; Jon Maloy <[email protected]>; Ying Xue > <[email protected]>; [email protected] > 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 <[email protected]> > Signed-off-by: Xin Long <[email protected]> > --- > 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
_______________________________________________ tipc-discussion mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/tipc-discussion
