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.

Merge branch 'net-followup-series-for-exit_rtnl'

Kuniyuki Iwashima says:

====================
net: Followup series for ->exit_rtnl().

Patch 1 drops the hold_rtnl arg in ops_undo_list() as suggested by Jakub.
Patch 2 & 3 apply ->exit_rtnl() to pfcp and ppp.

v1: https://lore.kernel.org/20250415022258.11491-1-kuniyu@amazon.com
====================

Link: https://patch.msgid.link/20250418003259.48017-1-kuniyu@amazon.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+29 -41
+7 -16
drivers/net/pfcp.c
··· 245 245 return 0; 246 246 } 247 247 248 - static void __net_exit pfcp_net_exit(struct net *net) 248 + static void __net_exit pfcp_net_exit_rtnl(struct net *net, 249 + struct list_head *dev_to_kill) 249 250 { 250 251 struct pfcp_net *pn = net_generic(net, pfcp_net_id); 251 252 struct pfcp_dev *pfcp, *pfcp_next; 252 - struct net_device *dev; 253 - LIST_HEAD(list); 254 - 255 - rtnl_lock(); 256 - for_each_netdev(net, dev) 257 - if (dev->rtnl_link_ops == &pfcp_link_ops) 258 - pfcp_dellink(dev, &list); 259 253 260 254 list_for_each_entry_safe(pfcp, pfcp_next, &pn->pfcp_dev_list, list) 261 - pfcp_dellink(pfcp->dev, &list); 262 - 263 - unregister_netdevice_many(&list); 264 - rtnl_unlock(); 255 + pfcp_dellink(pfcp->dev, dev_to_kill); 265 256 } 266 257 267 258 static struct pernet_operations pfcp_net_ops = { 268 - .init = pfcp_net_init, 269 - .exit = pfcp_net_exit, 270 - .id = &pfcp_net_id, 271 - .size = sizeof(struct pfcp_net), 259 + .init = pfcp_net_init, 260 + .exit_rtnl = pfcp_net_exit_rtnl, 261 + .id = &pfcp_net_id, 262 + .size = sizeof(struct pfcp_net), 272 263 }; 273 264 274 265 static int __init pfcp_init(void)
+14 -19
drivers/net/ppp/ppp_generic.c
··· 1131 1131 .llseek = noop_llseek, 1132 1132 }; 1133 1133 1134 + static void ppp_nl_dellink(struct net_device *dev, struct list_head *head); 1135 + 1134 1136 static __net_init int ppp_init_net(struct net *net) 1135 1137 { 1136 1138 struct ppp_net *pn = net_generic(net, ppp_net_id); ··· 1148 1146 return 0; 1149 1147 } 1150 1148 1149 + static __net_exit void ppp_exit_rtnl_net(struct net *net, 1150 + struct list_head *dev_to_kill) 1151 + { 1152 + struct ppp_net *pn = net_generic(net, ppp_net_id); 1153 + struct ppp *ppp; 1154 + int id; 1155 + 1156 + idr_for_each_entry(&pn->units_idr, ppp, id) 1157 + ppp_nl_dellink(ppp->dev, dev_to_kill); 1158 + } 1159 + 1151 1160 static __net_exit void ppp_exit_net(struct net *net) 1152 1161 { 1153 1162 struct ppp_net *pn = net_generic(net, ppp_net_id); 1154 - struct net_device *dev; 1155 - struct net_device *aux; 1156 - struct ppp *ppp; 1157 - LIST_HEAD(list); 1158 - int id; 1159 - 1160 - rtnl_lock(); 1161 - for_each_netdev_safe(net, dev, aux) { 1162 - if (dev->netdev_ops == &ppp_netdev_ops) 1163 - unregister_netdevice_queue(dev, &list); 1164 - } 1165 - 1166 - idr_for_each_entry(&pn->units_idr, ppp, id) 1167 - /* Skip devices already unregistered by previous loop */ 1168 - if (!net_eq(dev_net(ppp->dev), net)) 1169 - unregister_netdevice_queue(ppp->dev, &list); 1170 - 1171 - unregister_netdevice_many(&list); 1172 - rtnl_unlock(); 1173 1163 1174 1164 mutex_destroy(&pn->all_ppp_mutex); 1175 1165 idr_destroy(&pn->units_idr); ··· 1171 1177 1172 1178 static struct pernet_operations ppp_net_ops = { 1173 1179 .init = ppp_init_net, 1180 + .exit_rtnl = ppp_exit_rtnl_net, 1174 1181 .exit = ppp_exit_net, 1175 1182 .id = &ppp_net_id, 1176 1183 .size = sizeof(struct ppp_net),
+8 -6
net/core/net_namespace.c
··· 220 220 static void ops_undo_list(const struct list_head *ops_list, 221 221 const struct pernet_operations *ops, 222 222 struct list_head *net_exit_list, 223 - bool expedite_rcu, bool hold_rtnl) 223 + bool expedite_rcu) 224 224 { 225 225 const struct pernet_operations *saved_ops; 226 + bool hold_rtnl = false; 226 227 227 228 if (!ops) 228 229 ops = list_entry(ops_list, typeof(*ops), list); 229 230 230 231 saved_ops = ops; 231 232 232 - list_for_each_entry_continue_reverse(ops, ops_list, list) 233 + list_for_each_entry_continue_reverse(ops, ops_list, list) { 234 + hold_rtnl |= !!ops->exit_rtnl; 233 235 ops_pre_exit_list(ops, net_exit_list); 236 + } 234 237 235 238 /* Another CPU might be rcu-iterating the list, wait for it. 236 239 * This needs to be before calling the exit() notifiers, so the ··· 260 257 static void ops_undo_single(struct pernet_operations *ops, 261 258 struct list_head *net_exit_list) 262 259 { 263 - bool hold_rtnl = !!ops->exit_rtnl; 264 260 LIST_HEAD(ops_list); 265 261 266 262 list_add(&ops->list, &ops_list); 267 - ops_undo_list(&ops_list, NULL, net_exit_list, false, hold_rtnl); 263 + ops_undo_list(&ops_list, NULL, net_exit_list, false); 268 264 list_del(&ops->list); 269 265 } 270 266 ··· 454 452 * for the pernet modules whose init functions did not fail. 455 453 */ 456 454 list_add(&net->exit_list, &net_exit_list); 457 - ops_undo_list(&pernet_list, ops, &net_exit_list, false, true); 455 + ops_undo_list(&pernet_list, ops, &net_exit_list, false); 458 456 rcu_barrier(); 459 457 goto out; 460 458 } ··· 683 681 list_add_tail(&net->exit_list, &net_exit_list); 684 682 } 685 683 686 - ops_undo_list(&pernet_list, NULL, &net_exit_list, true, true); 684 + ops_undo_list(&pernet_list, NULL, &net_exit_list, true); 687 685 688 686 up_read(&pernet_ops_rwsem); 689 687