Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

tcp/dccp: do not care about families in inet_twsk_purge()

We lost ability to unload ipv6 module a long time ago.

Instead of calling expensive inet_twsk_purge() twice,
we can handle all families in one round.

Also remove an extra line added in my prior patch,
per Kuniyuki Iwashima feedback.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Link: https://lore.kernel.org/netdev/20240327192934.6843-1-kuniyu@amazon.com/
Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Link: https://lore.kernel.org/r/20240329153203.345203-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Eric Dumazet and committed by
Jakub Kicinski
1eeb5043 58169ec9

+10 -25
+1 -1
include/net/inet_timewait_sock.h
··· 111 111 112 112 void inet_twsk_deschedule_put(struct inet_timewait_sock *tw); 113 113 114 - void inet_twsk_purge(struct inet_hashinfo *hashinfo, int family); 114 + void inet_twsk_purge(struct inet_hashinfo *hashinfo); 115 115 116 116 static inline 117 117 struct net *twsk_net(const struct inet_timewait_sock *twsk)
+1 -1
include/net/tcp.h
··· 353 353 void tcp_rcv_space_adjust(struct sock *sk); 354 354 int tcp_twsk_unique(struct sock *sk, struct sock *sktw, void *twp); 355 355 void tcp_twsk_destructor(struct sock *sk); 356 - void tcp_twsk_purge(struct list_head *net_exit_list, int family); 356 + void tcp_twsk_purge(struct list_head *net_exit_list); 357 357 ssize_t tcp_splice_read(struct socket *sk, loff_t *ppos, 358 358 struct pipe_inode_info *pipe, size_t len, 359 359 unsigned int flags);
+1 -1
net/dccp/ipv4.c
··· 1039 1039 1040 1040 static void __net_exit dccp_v4_exit_batch(struct list_head *net_exit_list) 1041 1041 { 1042 - inet_twsk_purge(&dccp_hashinfo, AF_INET); 1042 + inet_twsk_purge(&dccp_hashinfo); 1043 1043 } 1044 1044 1045 1045 static struct pernet_operations dccp_v4_ops = {
-6
net/dccp/ipv6.c
··· 1119 1119 inet_ctl_sock_destroy(pn->v6_ctl_sk); 1120 1120 } 1121 1121 1122 - static void __net_exit dccp_v6_exit_batch(struct list_head *net_exit_list) 1123 - { 1124 - inet_twsk_purge(&dccp_hashinfo, AF_INET6); 1125 - } 1126 - 1127 1122 static struct pernet_operations dccp_v6_ops = { 1128 1123 .init = dccp_v6_init_net, 1129 1124 .exit = dccp_v6_exit_net, 1130 - .exit_batch = dccp_v6_exit_batch, 1131 1125 .id = &dccp_v6_pernet_id, 1132 1126 .size = sizeof(struct dccp_v6_pernet), 1133 1127 };
+3 -6
net/ipv4/inet_timewait_sock.c
··· 264 264 EXPORT_SYMBOL_GPL(__inet_twsk_schedule); 265 265 266 266 /* Remove all non full sockets (TIME_WAIT and NEW_SYN_RECV) for dead netns */ 267 - void inet_twsk_purge(struct inet_hashinfo *hashinfo, int family) 267 + void inet_twsk_purge(struct inet_hashinfo *hashinfo) 268 268 { 269 269 struct inet_ehash_bucket *head = &hashinfo->ehash[0]; 270 270 unsigned int ehash_mask = hashinfo->ehash_mask; ··· 273 273 struct sock *sk; 274 274 275 275 for (slot = 0; slot <= ehash_mask; slot++, head++) { 276 - 277 276 if (hlist_nulls_empty(&head->chain)) 278 277 continue; 279 278 ··· 287 288 TCPF_NEW_SYN_RECV)) 288 289 continue; 289 290 290 - if (sk->sk_family != family || 291 - refcount_read(&sock_net(sk)->ns.count)) 291 + if (refcount_read(&sock_net(sk)->ns.count)) 292 292 continue; 293 293 294 294 if (unlikely(!refcount_inc_not_zero(&sk->sk_refcnt))) 295 295 continue; 296 296 297 - if (unlikely(sk->sk_family != family || 298 - refcount_read(&sock_net(sk)->ns.count))) { 297 + if (refcount_read(&sock_net(sk)->ns.count)) { 299 298 sock_gen_put(sk); 300 299 goto restart; 301 300 }
+1 -1
net/ipv4/tcp_ipv4.c
··· 3501 3501 { 3502 3502 struct net *net; 3503 3503 3504 - tcp_twsk_purge(net_exit_list, AF_INET); 3504 + tcp_twsk_purge(net_exit_list); 3505 3505 3506 3506 list_for_each_entry(net, net_exit_list, exit_list) { 3507 3507 inet_pernet_hashinfo_free(net->ipv4.tcp_death_row.hashinfo);
+3 -3
net/ipv4/tcp_minisocks.c
··· 388 388 } 389 389 EXPORT_SYMBOL_GPL(tcp_twsk_destructor); 390 390 391 - void tcp_twsk_purge(struct list_head *net_exit_list, int family) 391 + void tcp_twsk_purge(struct list_head *net_exit_list) 392 392 { 393 393 bool purged_once = false; 394 394 struct net *net; ··· 396 396 list_for_each_entry(net, net_exit_list, exit_list) { 397 397 if (net->ipv4.tcp_death_row.hashinfo->pernet) { 398 398 /* Even if tw_refcount == 1, we must clean up kernel reqsk */ 399 - inet_twsk_purge(net->ipv4.tcp_death_row.hashinfo, family); 399 + inet_twsk_purge(net->ipv4.tcp_death_row.hashinfo); 400 400 } else if (!purged_once) { 401 - inet_twsk_purge(&tcp_hashinfo, family); 401 + inet_twsk_purge(&tcp_hashinfo); 402 402 purged_once = true; 403 403 } 404 404 }
-6
net/ipv6/tcp_ipv6.c
··· 2389 2389 inet_ctl_sock_destroy(net->ipv6.tcp_sk); 2390 2390 } 2391 2391 2392 - static void __net_exit tcpv6_net_exit_batch(struct list_head *net_exit_list) 2393 - { 2394 - tcp_twsk_purge(net_exit_list, AF_INET6); 2395 - } 2396 - 2397 2392 static struct pernet_operations tcpv6_net_ops = { 2398 2393 .init = tcpv6_net_init, 2399 2394 .exit = tcpv6_net_exit, 2400 - .exit_batch = tcpv6_net_exit_batch, 2401 2395 }; 2402 2396 2403 2397 int __init tcpv6_init(void)