@@ -2246,6 +2246,7 @@ struct sock *sk_alloc(struct net *net, int family, gfp_t priority,
22462246 get_net_track (net , & sk -> ns_tracker , priority );
22472247 sock_inuse_add (net , 1 );
22482248 } else {
2249+ net_passive_inc (net );
22492250 __netns_tracker_alloc (net , & sk -> ns_tracker ,
22502251 false, priority );
22512252 }
@@ -2270,6 +2271,7 @@ EXPORT_SYMBOL(sk_alloc);
22702271static void __sk_destruct (struct rcu_head * head )
22712272{
22722273 struct sock * sk = container_of (head , struct sock , sk_rcu );
2274+ struct net * net = sock_net (sk );
22732275 struct sk_filter * filter ;
22742276
22752277 if (sk -> sk_destruct )
@@ -2301,14 +2303,28 @@ static void __sk_destruct(struct rcu_head *head)
23012303 put_cred (sk -> sk_peer_cred );
23022304 put_pid (sk -> sk_peer_pid );
23032305
2304- if (likely (sk -> sk_net_refcnt ))
2305- put_net_track (sock_net (sk ), & sk -> ns_tracker );
2306- else
2307- __netns_tracker_free (sock_net (sk ), & sk -> ns_tracker , false);
2308-
2306+ if (likely (sk -> sk_net_refcnt )) {
2307+ put_net_track (net , & sk -> ns_tracker );
2308+ } else {
2309+ __netns_tracker_free (net , & sk -> ns_tracker , false);
2310+ net_passive_dec (net );
2311+ }
23092312 sk_prot_free (sk -> sk_prot_creator , sk );
23102313}
23112314
2315+ void sk_net_refcnt_upgrade (struct sock * sk )
2316+ {
2317+ struct net * net = sock_net (sk );
2318+
2319+ WARN_ON_ONCE (sk -> sk_net_refcnt );
2320+ __netns_tracker_free (net , & sk -> ns_tracker , false);
2321+ net_passive_dec (net );
2322+ sk -> sk_net_refcnt = 1 ;
2323+ get_net_track (net , & sk -> ns_tracker , GFP_KERNEL );
2324+ sock_inuse_add (net , 1 );
2325+ }
2326+ EXPORT_SYMBOL_GPL (sk_net_refcnt_upgrade );
2327+
23122328void sk_destruct (struct sock * sk )
23132329{
23142330 bool use_call_rcu = sock_flag (sk , SOCK_RCU_FREE );
@@ -2405,6 +2421,7 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority)
24052421 * is not properly dismantling its kernel sockets at netns
24062422 * destroy time.
24072423 */
2424+ net_passive_inc (sock_net (newsk ));
24082425 __netns_tracker_alloc (sock_net (newsk ), & newsk -> ns_tracker ,
24092426 false, priority );
24102427 }
0 commit comments