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.

ipmr: Move unregister_netdevice_many() out of ipmr_free_table().

This is a prep commit to convert ipmr_net_exit_batch() to
->exit_rtnl().

Let's move unregister_netdevice_many() in ipmr_free_table()
to its callers.

Now ipmr_rules_exit() can do batching all tables per netns.

Note that later we will remove RTNL and unregister_netdevice_many()
in ipmr_rules_init().

Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20260228221800.1082070-9-kuniyu@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Kuniyuki Iwashima and committed by
Jakub Kicinski
b7fdc3cf 3810f952

+17 -8
+17 -8
net/ipv4/ipmr.c
··· 102 102 static struct kmem_cache *mrt_cachep __ro_after_init; 103 103 104 104 static struct mr_table *ipmr_new_table(struct net *net, u32 id); 105 - static void ipmr_free_table(struct mr_table *mrt); 105 + static void ipmr_free_table(struct mr_table *mrt, 106 + struct list_head *dev_kill_list); 106 107 107 108 static void ip_mr_forward(struct net *net, struct mr_table *mrt, 108 109 struct net_device *dev, struct sk_buff *skb, ··· 252 251 static int __net_init ipmr_rules_init(struct net *net) 253 252 { 254 253 struct fib_rules_ops *ops; 254 + LIST_HEAD(dev_kill_list); 255 255 struct mr_table *mrt; 256 256 int err; 257 257 ··· 277 275 278 276 err2: 279 277 rtnl_lock(); 280 - ipmr_free_table(mrt); 278 + ipmr_free_table(mrt, &dev_kill_list); 279 + unregister_netdevice_many(&dev_kill_list); 281 280 rtnl_unlock(); 282 281 err1: 283 282 fib_rules_unregister(ops); ··· 288 285 static void __net_exit ipmr_rules_exit(struct net *net) 289 286 { 290 287 struct mr_table *mrt, *next; 288 + LIST_HEAD(dev_kill_list); 291 289 292 290 ASSERT_RTNL(); 293 291 list_for_each_entry_safe(mrt, next, &net->ipv4.mr_tables, list) { 294 292 list_del(&mrt->list); 295 - ipmr_free_table(mrt); 293 + ipmr_free_table(mrt, &dev_kill_list); 296 294 } 295 + 296 + unregister_netdevice_many(&dev_kill_list); 297 297 fib_rules_unregister(net->ipv4.mr_rules_ops); 298 298 } 299 299 ··· 355 349 356 350 static void __net_exit ipmr_rules_exit(struct net *net) 357 351 { 352 + LIST_HEAD(dev_kill_list); 353 + 358 354 ASSERT_RTNL(); 359 - ipmr_free_table(net->ipv4.mrt); 355 + 356 + ipmr_free_table(net->ipv4.mrt, &dev_kill_list); 357 + unregister_netdevice_many(&dev_kill_list); 358 + 360 359 net->ipv4.mrt = NULL; 361 360 } 362 361 ··· 436 425 ipmr_expire_process, ipmr_new_table_set); 437 426 } 438 427 439 - static void ipmr_free_table(struct mr_table *mrt) 428 + static void ipmr_free_table(struct mr_table *mrt, struct list_head *dev_kill_list) 440 429 { 441 430 struct net *net = read_pnet(&mrt->net); 442 - LIST_HEAD(dev_kill_list); 443 431 444 432 WARN_ON_ONCE(!mr_can_free_table(net)); 445 433 446 434 timer_shutdown_sync(&mrt->ipmr_expire_timer); 447 435 mroute_clean_tables(mrt, MRT_FLUSH_VIFS | MRT_FLUSH_VIFS_STATIC | 448 436 MRT_FLUSH_MFC | MRT_FLUSH_MFC_STATIC, 449 - &dev_kill_list); 450 - unregister_netdevice_many(&dev_kill_list); 437 + dev_kill_list); 451 438 rhltable_destroy(&mrt->mfc_hash); 452 439 kfree(mrt); 453 440 }