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

rds: tcp: remove register_netdevice_notifier infrastructure.

The netns deletion path does not need to wait for all net_devices
to be unregistered before dismantling rds_tcp state for the netns
(we are able to dismantle this state on module unload even when
all net_devices are active so there is no dependency here).

This patch removes code related to netdevice notifiers and
refactors all the code needed to dismantle rds_tcp state
into a ->exit callback for the pernet_operations used with
register_pernet_device().

Signed-off-by: Sowmini Varadhan <sowmini.varadhan@oracle.com>
Reviewed-by: Kirill Tkhai <ktkhai@virtuozzo.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Sowmini Varadhan and committed by
David S. Miller
bdf5bd7f 692ec06d

+23 -70
+23 -70
net/rds/tcp.c
··· 485 485 return err; 486 486 } 487 487 488 - static void __net_exit rds_tcp_exit_net(struct net *net) 489 - { 490 - struct rds_tcp_net *rtn = net_generic(net, rds_tcp_netid); 491 - 492 - if (rtn->rds_tcp_sysctl) 493 - unregister_net_sysctl_table(rtn->rds_tcp_sysctl); 494 - 495 - if (net != &init_net && rtn->ctl_table) 496 - kfree(rtn->ctl_table); 497 - 498 - /* If rds_tcp_exit_net() is called as a result of netns deletion, 499 - * the rds_tcp_kill_sock() device notifier would already have cleaned 500 - * up the listen socket, thus there is no work to do in this function. 501 - * 502 - * If rds_tcp_exit_net() is called as a result of module unload, 503 - * i.e., due to rds_tcp_exit() -> unregister_pernet_subsys(), then 504 - * we do need to clean up the listen socket here. 505 - */ 506 - if (rtn->rds_tcp_listen_sock) { 507 - struct socket *lsock = rtn->rds_tcp_listen_sock; 508 - 509 - rtn->rds_tcp_listen_sock = NULL; 510 - rds_tcp_listen_stop(lsock, &rtn->rds_tcp_accept_w); 511 - } 512 - } 513 - 514 - static struct pernet_operations rds_tcp_net_ops = { 515 - .init = rds_tcp_init_net, 516 - .exit = rds_tcp_exit_net, 517 - .id = &rds_tcp_netid, 518 - .size = sizeof(struct rds_tcp_net), 519 - .async = true, 520 - }; 521 - 522 488 static void rds_tcp_kill_sock(struct net *net) 523 489 { 524 490 struct rds_tcp_connection *tc, *_tc; ··· 512 546 rds_conn_destroy(tc->t_cpath->cp_conn); 513 547 } 514 548 549 + static void __net_exit rds_tcp_exit_net(struct net *net) 550 + { 551 + struct rds_tcp_net *rtn = net_generic(net, rds_tcp_netid); 552 + 553 + rds_tcp_kill_sock(net); 554 + 555 + if (rtn->rds_tcp_sysctl) 556 + unregister_net_sysctl_table(rtn->rds_tcp_sysctl); 557 + 558 + if (net != &init_net && rtn->ctl_table) 559 + kfree(rtn->ctl_table); 560 + } 561 + 562 + static struct pernet_operations rds_tcp_net_ops = { 563 + .init = rds_tcp_init_net, 564 + .exit = rds_tcp_exit_net, 565 + .id = &rds_tcp_netid, 566 + .size = sizeof(struct rds_tcp_net), 567 + .async = true, 568 + }; 569 + 515 570 void *rds_tcp_listen_sock_def_readable(struct net *net) 516 571 { 517 572 struct rds_tcp_net *rtn = net_generic(net, rds_tcp_netid); ··· 543 556 544 557 return lsock->sk->sk_user_data; 545 558 } 546 - 547 - static int rds_tcp_dev_event(struct notifier_block *this, 548 - unsigned long event, void *ptr) 549 - { 550 - struct net_device *dev = netdev_notifier_info_to_dev(ptr); 551 - 552 - /* rds-tcp registers as a pernet subys, so the ->exit will only 553 - * get invoked after network acitivity has quiesced. We need to 554 - * clean up all sockets to quiesce network activity, and use 555 - * the unregistration of the per-net loopback device as a trigger 556 - * to start that cleanup. 557 - */ 558 - if (event == NETDEV_UNREGISTER_FINAL && 559 - dev->ifindex == LOOPBACK_IFINDEX) 560 - rds_tcp_kill_sock(dev_net(dev)); 561 - 562 - return NOTIFY_DONE; 563 - } 564 - 565 - static struct notifier_block rds_tcp_dev_notifier = { 566 - .notifier_call = rds_tcp_dev_event, 567 - .priority = -10, /* must be called after other network notifiers */ 568 - }; 569 559 570 560 /* when sysctl is used to modify some kernel socket parameters,this 571 561 * function resets the RDS connections in that netns so that we can ··· 589 625 rds_tcp_set_unloading(); 590 626 synchronize_rcu(); 591 627 rds_info_deregister_func(RDS_INFO_TCP_SOCKETS, rds_tcp_tc_info); 592 - unregister_pernet_subsys(&rds_tcp_net_ops); 593 - if (unregister_netdevice_notifier(&rds_tcp_dev_notifier)) 594 - pr_warn("could not unregister rds_tcp_dev_notifier\n"); 628 + unregister_pernet_device(&rds_tcp_net_ops); 595 629 rds_tcp_destroy_conns(); 596 630 rds_trans_unregister(&rds_tcp_transport); 597 631 rds_tcp_recv_exit(); ··· 613 651 if (ret) 614 652 goto out_slab; 615 653 616 - ret = register_pernet_subsys(&rds_tcp_net_ops); 654 + ret = register_pernet_device(&rds_tcp_net_ops); 617 655 if (ret) 618 656 goto out_recv; 619 - 620 - ret = register_netdevice_notifier(&rds_tcp_dev_notifier); 621 - if (ret) { 622 - pr_warn("could not register rds_tcp_dev_notifier\n"); 623 - goto out_pernet; 624 - } 625 657 626 658 rds_trans_register(&rds_tcp_transport); 627 659 628 660 rds_info_register_func(RDS_INFO_TCP_SOCKETS, rds_tcp_tc_info); 629 661 630 662 goto out; 631 - 632 - out_pernet: 633 - unregister_pernet_subsys(&rds_tcp_net_ops); 634 663 out_recv: 635 664 rds_tcp_recv_exit(); 636 665 out_slab: