Commit bdf5bd7f21323493dbe5f2c723dc33f2fbb0241a
Committed by
David S. Miller
1 parent
692ec06d7c
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>
Showing 1 changed file with 23 additions and 70 deletions Side-by-side Diff
net/rds/tcp.c
... | ... | @@ -485,40 +485,6 @@ |
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; |
... | ... | @@ -546,6 +512,27 @@ |
546 | 512 | rds_conn_destroy(tc->t_cpath->cp_conn); |
547 | 513 | } |
548 | 514 | |
515 | +static void __net_exit rds_tcp_exit_net(struct net *net) | |
516 | +{ | |
517 | + struct rds_tcp_net *rtn = net_generic(net, rds_tcp_netid); | |
518 | + | |
519 | + rds_tcp_kill_sock(net); | |
520 | + | |
521 | + if (rtn->rds_tcp_sysctl) | |
522 | + unregister_net_sysctl_table(rtn->rds_tcp_sysctl); | |
523 | + | |
524 | + if (net != &init_net && rtn->ctl_table) | |
525 | + kfree(rtn->ctl_table); | |
526 | +} | |
527 | + | |
528 | +static struct pernet_operations rds_tcp_net_ops = { | |
529 | + .init = rds_tcp_init_net, | |
530 | + .exit = rds_tcp_exit_net, | |
531 | + .id = &rds_tcp_netid, | |
532 | + .size = sizeof(struct rds_tcp_net), | |
533 | + .async = true, | |
534 | +}; | |
535 | + | |
549 | 536 | void *rds_tcp_listen_sock_def_readable(struct net *net) |
550 | 537 | { |
551 | 538 | struct rds_tcp_net *rtn = net_generic(net, rds_tcp_netid); |
... | ... | @@ -557,29 +544,6 @@ |
557 | 544 | return lsock->sk->sk_user_data; |
558 | 545 | } |
559 | 546 | |
560 | -static int rds_tcp_dev_event(struct notifier_block *this, | |
561 | - unsigned long event, void *ptr) | |
562 | -{ | |
563 | - struct net_device *dev = netdev_notifier_info_to_dev(ptr); | |
564 | - | |
565 | - /* rds-tcp registers as a pernet subys, so the ->exit will only | |
566 | - * get invoked after network acitivity has quiesced. We need to | |
567 | - * clean up all sockets to quiesce network activity, and use | |
568 | - * the unregistration of the per-net loopback device as a trigger | |
569 | - * to start that cleanup. | |
570 | - */ | |
571 | - if (event == NETDEV_UNREGISTER_FINAL && | |
572 | - dev->ifindex == LOOPBACK_IFINDEX) | |
573 | - rds_tcp_kill_sock(dev_net(dev)); | |
574 | - | |
575 | - return NOTIFY_DONE; | |
576 | -} | |
577 | - | |
578 | -static struct notifier_block rds_tcp_dev_notifier = { | |
579 | - .notifier_call = rds_tcp_dev_event, | |
580 | - .priority = -10, /* must be called after other network notifiers */ | |
581 | -}; | |
582 | - | |
583 | 547 | /* when sysctl is used to modify some kernel socket parameters,this |
584 | 548 | * function resets the RDS connections in that netns so that we can |
585 | 549 | * restart with new parameters. The assumption is that such reset |
... | ... | @@ -625,9 +589,7 @@ |
625 | 589 | rds_tcp_set_unloading(); |
626 | 590 | synchronize_rcu(); |
627 | 591 | rds_info_deregister_func(RDS_INFO_TCP_SOCKETS, rds_tcp_tc_info); |
628 | - unregister_pernet_subsys(&rds_tcp_net_ops); | |
629 | - if (unregister_netdevice_notifier(&rds_tcp_dev_notifier)) | |
630 | - pr_warn("could not unregister rds_tcp_dev_notifier\n"); | |
592 | + unregister_pernet_device(&rds_tcp_net_ops); | |
631 | 593 | rds_tcp_destroy_conns(); |
632 | 594 | rds_trans_unregister(&rds_tcp_transport); |
633 | 595 | rds_tcp_recv_exit(); |
634 | 596 | |
635 | 597 | |
... | ... | @@ -651,24 +613,15 @@ |
651 | 613 | if (ret) |
652 | 614 | goto out_slab; |
653 | 615 | |
654 | - ret = register_pernet_subsys(&rds_tcp_net_ops); | |
616 | + ret = register_pernet_device(&rds_tcp_net_ops); | |
655 | 617 | if (ret) |
656 | 618 | goto out_recv; |
657 | 619 | |
658 | - ret = register_netdevice_notifier(&rds_tcp_dev_notifier); | |
659 | - if (ret) { | |
660 | - pr_warn("could not register rds_tcp_dev_notifier\n"); | |
661 | - goto out_pernet; | |
662 | - } | |
663 | - | |
664 | 620 | rds_trans_register(&rds_tcp_transport); |
665 | 621 | |
666 | 622 | rds_info_register_func(RDS_INFO_TCP_SOCKETS, rds_tcp_tc_info); |
667 | 623 | |
668 | 624 | goto out; |
669 | - | |
670 | -out_pernet: | |
671 | - unregister_pernet_subsys(&rds_tcp_net_ops); | |
672 | 625 | out_recv: |
673 | 626 | rds_tcp_recv_exit(); |
674 | 627 | out_slab: |