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

Merge branch 'mlxsw-cleanups'

Petr Machata says:

====================
mlxsw: Cleanups in router code

This patchset moves some router-related code from spectrum.c to
spectrum_router.c where it should be. It also simplifies handlers of
netevent notifications.

- Patch #1 caches router pointer in a dedicated variable. This obviates the
need to access the same as mlxsw_sp->router, making lines shorter, and
permitting a future patch to add code that fits within 80 character
limit.

- Patch #2 moves IP / IPv6 validation notifier blocks from spectrum.c
to spectrum_router, where the handlers are anyway.

- In patch #3, pass router pointer to scheduler of deferred work directly,
instead of having it deduce it on its own.

- This makes the router pointer available in the handler function
mlxsw_sp_router_netevent_event(), so in patch #4, use it directly,
instead of finding it through mlxsw_sp_port.

- In patch #5, extend mlxsw_sp_router_schedule_work() so that the
NETEVENT_NEIGH_UPDATE handler can use it directly instead of inlining
equivalent code.

- In patches #6 and #7, add helpers for two common operations involving
a backing netdev of a RIF. This makes it unnecessary for the function
mlxsw_sp_rif_dev() to be visible outside of the router module, so in
patch #8, hide it.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+89 -81
+1 -17
drivers/net/ethernet/mellanox/mlxsw/spectrum.c
··· 5139 5139 return notifier_from_errno(err); 5140 5140 } 5141 5141 5142 - static struct notifier_block mlxsw_sp_inetaddr_valid_nb __read_mostly = { 5143 - .notifier_call = mlxsw_sp_inetaddr_valid_event, 5144 - }; 5145 - 5146 - static struct notifier_block mlxsw_sp_inet6addr_valid_nb __read_mostly = { 5147 - .notifier_call = mlxsw_sp_inet6addr_valid_event, 5148 - }; 5149 - 5150 5142 static const struct pci_device_id mlxsw_sp1_pci_id_table[] = { 5151 5143 {PCI_VDEVICE(MELLANOX, PCI_DEVICE_ID_MELLANOX_SPECTRUM), 0}, 5152 5144 {0, }, ··· 5183 5191 { 5184 5192 int err; 5185 5193 5186 - register_inetaddr_validator_notifier(&mlxsw_sp_inetaddr_valid_nb); 5187 - register_inet6addr_validator_notifier(&mlxsw_sp_inet6addr_valid_nb); 5188 - 5189 5194 err = mlxsw_core_driver_register(&mlxsw_sp1_driver); 5190 5195 if (err) 5191 - goto err_sp1_core_driver_register; 5196 + return err; 5192 5197 5193 5198 err = mlxsw_core_driver_register(&mlxsw_sp2_driver); 5194 5199 if (err) ··· 5231 5242 mlxsw_core_driver_unregister(&mlxsw_sp2_driver); 5232 5243 err_sp2_core_driver_register: 5233 5244 mlxsw_core_driver_unregister(&mlxsw_sp1_driver); 5234 - err_sp1_core_driver_register: 5235 - unregister_inet6addr_validator_notifier(&mlxsw_sp_inet6addr_valid_nb); 5236 - unregister_inetaddr_validator_notifier(&mlxsw_sp_inetaddr_valid_nb); 5237 5245 return err; 5238 5246 } 5239 5247 ··· 5244 5258 mlxsw_core_driver_unregister(&mlxsw_sp3_driver); 5245 5259 mlxsw_core_driver_unregister(&mlxsw_sp2_driver); 5246 5260 mlxsw_core_driver_unregister(&mlxsw_sp1_driver); 5247 - unregister_inet6addr_validator_notifier(&mlxsw_sp_inet6addr_valid_nb); 5248 - unregister_inetaddr_validator_notifier(&mlxsw_sp_inetaddr_valid_nb); 5249 5261 } 5250 5262 5251 5263 module_init(mlxsw_sp_module_init);
-4
drivers/net/ethernet/mellanox/mlxsw/spectrum.h
··· 755 755 void mlxsw_sp_router_fini(struct mlxsw_sp *mlxsw_sp); 756 756 void mlxsw_sp_rif_macvlan_del(struct mlxsw_sp *mlxsw_sp, 757 757 const struct net_device *macvlan_dev); 758 - int mlxsw_sp_inetaddr_valid_event(struct notifier_block *unused, 759 - unsigned long event, void *ptr); 760 - int mlxsw_sp_inet6addr_valid_event(struct notifier_block *unused, 761 - unsigned long event, void *ptr); 762 758 int 763 759 mlxsw_sp_port_vlan_router_join(struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan, 764 760 struct net_device *l3_dev,
+1 -1
drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c
··· 221 221 for (; i < rif_count; i++) { 222 222 struct mlxsw_sp_rif *rif = mlxsw_sp_rif_by_index(mlxsw_sp, i); 223 223 224 - if (!rif || !mlxsw_sp_rif_dev(rif)) 224 + if (!rif || !mlxsw_sp_rif_has_dev(rif)) 225 225 continue; 226 226 err = mlxsw_sp_erif_entry_get(mlxsw_sp, &entry, rif, 227 227 counters_enabled);
+8 -11
drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c
··· 704 704 705 705 static struct mlxsw_sp_mr_vif * 706 706 mlxsw_sp_mr_dev_vif_lookup(struct mlxsw_sp_mr_table *mr_table, 707 - const struct net_device *dev) 707 + const struct mlxsw_sp_rif *rif) 708 708 { 709 709 vifi_t vif_index; 710 710 711 711 for (vif_index = 0; vif_index < MAXVIFS; vif_index++) 712 - if (mr_table->vifs[vif_index].dev == dev) 712 + if (mlxsw_sp_rif_dev_is(rif, mr_table->vifs[vif_index].dev)) 713 713 return &mr_table->vifs[vif_index]; 714 714 return NULL; 715 715 } ··· 717 717 int mlxsw_sp_mr_rif_add(struct mlxsw_sp_mr_table *mr_table, 718 718 const struct mlxsw_sp_rif *rif) 719 719 { 720 - const struct net_device *rif_dev = mlxsw_sp_rif_dev(rif); 721 720 struct mlxsw_sp_mr_vif *mr_vif; 722 721 723 - if (!rif_dev) 722 + if (!mlxsw_sp_rif_has_dev(rif)) 724 723 return 0; 725 724 726 - mr_vif = mlxsw_sp_mr_dev_vif_lookup(mr_table, rif_dev); 725 + mr_vif = mlxsw_sp_mr_dev_vif_lookup(mr_table, rif); 727 726 if (!mr_vif) 728 727 return 0; 729 728 return mlxsw_sp_mr_vif_resolve(mr_table, mr_vif->dev, mr_vif, ··· 732 733 void mlxsw_sp_mr_rif_del(struct mlxsw_sp_mr_table *mr_table, 733 734 const struct mlxsw_sp_rif *rif) 734 735 { 735 - const struct net_device *rif_dev = mlxsw_sp_rif_dev(rif); 736 736 struct mlxsw_sp_mr_vif *mr_vif; 737 737 738 - if (!rif_dev) 738 + if (!mlxsw_sp_rif_has_dev(rif)) 739 739 return; 740 740 741 - mr_vif = mlxsw_sp_mr_dev_vif_lookup(mr_table, rif_dev); 741 + mr_vif = mlxsw_sp_mr_dev_vif_lookup(mr_table, rif); 742 742 if (!mr_vif) 743 743 return; 744 744 mlxsw_sp_mr_vif_unresolve(mr_table, mr_vif->dev, mr_vif); ··· 746 748 void mlxsw_sp_mr_rif_mtu_update(struct mlxsw_sp_mr_table *mr_table, 747 749 const struct mlxsw_sp_rif *rif, int mtu) 748 750 { 749 - const struct net_device *rif_dev = mlxsw_sp_rif_dev(rif); 750 751 struct mlxsw_sp *mlxsw_sp = mr_table->mlxsw_sp; 751 752 struct mlxsw_sp_mr_route_vif_entry *rve; 752 753 struct mlxsw_sp_mr *mr = mlxsw_sp->mr; 753 754 struct mlxsw_sp_mr_vif *mr_vif; 754 755 755 - if (!rif_dev) 756 + if (!mlxsw_sp_rif_has_dev(rif)) 756 757 return; 757 758 758 759 /* Search for a VIF that use that RIF */ 759 - mr_vif = mlxsw_sp_mr_dev_vif_lookup(mr_table, rif_dev); 760 + mr_vif = mlxsw_sp_mr_dev_vif_lookup(mr_table, rif); 760 761 if (!mr_vif) 761 762 return; 762 763
+74 -47
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
··· 2748 2748 } 2749 2749 2750 2750 static int mlxsw_sp_router_schedule_work(struct net *net, 2751 - struct notifier_block *nb, 2751 + struct mlxsw_sp_router *router, 2752 + struct neighbour *n, 2752 2753 void (*cb)(struct work_struct *)) 2753 2754 { 2754 2755 struct mlxsw_sp_netevent_work *net_work; 2755 - struct mlxsw_sp_router *router; 2756 2756 2757 - router = container_of(nb, struct mlxsw_sp_router, netevent_nb); 2758 2757 if (!net_eq(net, mlxsw_sp_net(router->mlxsw_sp))) 2759 2758 return NOTIFY_DONE; 2760 2759 ··· 2763 2764 2764 2765 INIT_WORK(&net_work->work, cb); 2765 2766 net_work->mlxsw_sp = router->mlxsw_sp; 2767 + net_work->n = n; 2766 2768 mlxsw_core_schedule_work(&net_work->work); 2767 2769 return NOTIFY_DONE; 2770 + } 2771 + 2772 + static bool mlxsw_sp_dev_lower_is_port(struct net_device *dev) 2773 + { 2774 + struct mlxsw_sp_port *mlxsw_sp_port; 2775 + 2776 + rcu_read_lock(); 2777 + mlxsw_sp_port = mlxsw_sp_port_dev_lower_find_rcu(dev); 2778 + rcu_read_unlock(); 2779 + return !!mlxsw_sp_port; 2768 2780 } 2769 2781 2770 2782 static int mlxsw_sp_router_netevent_event(struct notifier_block *nb, 2771 2783 unsigned long event, void *ptr) 2772 2784 { 2773 - struct mlxsw_sp_netevent_work *net_work; 2774 - struct mlxsw_sp_port *mlxsw_sp_port; 2775 - struct mlxsw_sp *mlxsw_sp; 2785 + struct mlxsw_sp_router *router; 2776 2786 unsigned long interval; 2777 2787 struct neigh_parms *p; 2778 2788 struct neighbour *n; 2789 + struct net *net; 2790 + 2791 + router = container_of(nb, struct mlxsw_sp_router, netevent_nb); 2779 2792 2780 2793 switch (event) { 2781 2794 case NETEVENT_DELAY_PROBE_TIME_UPDATE: ··· 2801 2790 /* We are in atomic context and can't take RTNL mutex, 2802 2791 * so use RCU variant to walk the device chain. 2803 2792 */ 2804 - mlxsw_sp_port = mlxsw_sp_port_lower_dev_hold(p->dev); 2805 - if (!mlxsw_sp_port) 2793 + if (!mlxsw_sp_dev_lower_is_port(p->dev)) 2806 2794 return NOTIFY_DONE; 2807 2795 2808 - mlxsw_sp = mlxsw_sp_port->mlxsw_sp; 2809 2796 interval = jiffies_to_msecs(NEIGH_VAR(p, DELAY_PROBE_TIME)); 2810 - mlxsw_sp->router->neighs_update.interval = interval; 2811 - 2812 - mlxsw_sp_port_dev_put(mlxsw_sp_port); 2797 + router->neighs_update.interval = interval; 2813 2798 break; 2814 2799 case NETEVENT_NEIGH_UPDATE: 2815 2800 n = ptr; 2801 + net = neigh_parms_net(n->parms); 2816 2802 2817 2803 if (n->tbl->family != AF_INET && n->tbl->family != AF_INET6) 2818 2804 return NOTIFY_DONE; 2819 2805 2820 - mlxsw_sp_port = mlxsw_sp_port_lower_dev_hold(n->dev); 2821 - if (!mlxsw_sp_port) 2806 + if (!mlxsw_sp_dev_lower_is_port(n->dev)) 2822 2807 return NOTIFY_DONE; 2823 - 2824 - net_work = kzalloc(sizeof(*net_work), GFP_ATOMIC); 2825 - if (!net_work) { 2826 - mlxsw_sp_port_dev_put(mlxsw_sp_port); 2827 - return NOTIFY_BAD; 2828 - } 2829 - 2830 - INIT_WORK(&net_work->work, mlxsw_sp_router_neigh_event_work); 2831 - net_work->mlxsw_sp = mlxsw_sp_port->mlxsw_sp; 2832 - net_work->n = n; 2833 2808 2834 2809 /* Take a reference to ensure the neighbour won't be 2835 2810 * destructed until we drop the reference in delayed 2836 2811 * work. 2837 2812 */ 2838 2813 neigh_clone(n); 2839 - mlxsw_core_schedule_work(&net_work->work); 2840 - mlxsw_sp_port_dev_put(mlxsw_sp_port); 2841 - break; 2814 + return mlxsw_sp_router_schedule_work(net, router, n, 2815 + mlxsw_sp_router_neigh_event_work); 2816 + 2842 2817 case NETEVENT_IPV4_MPATH_HASH_UPDATE: 2843 2818 case NETEVENT_IPV6_MPATH_HASH_UPDATE: 2844 - return mlxsw_sp_router_schedule_work(ptr, nb, 2819 + return mlxsw_sp_router_schedule_work(ptr, router, NULL, 2845 2820 mlxsw_sp_router_mp_hash_event_work); 2846 2821 2847 2822 case NETEVENT_IPV4_FWD_UPDATE_PRIORITY_UPDATE: 2848 - return mlxsw_sp_router_schedule_work(ptr, nb, 2823 + return mlxsw_sp_router_schedule_work(ptr, router, NULL, 2849 2824 mlxsw_sp_router_update_priority_work); 2850 2825 } 2851 2826 ··· 7705 7708 7706 7709 for (i = 0; i < max_rifs; i++) 7707 7710 if (mlxsw_sp->router->rifs[i] && 7708 - mlxsw_sp->router->rifs[i]->dev == dev) 7711 + mlxsw_sp_rif_dev_is(mlxsw_sp->router->rifs[i], dev)) 7709 7712 return mlxsw_sp->router->rifs[i]; 7710 7713 7711 7714 return NULL; ··· 8075 8078 return rif->dev->ifindex; 8076 8079 } 8077 8080 8078 - const struct net_device *mlxsw_sp_rif_dev(const struct mlxsw_sp_rif *rif) 8081 + static const struct net_device *mlxsw_sp_rif_dev(const struct mlxsw_sp_rif *rif) 8079 8082 { 8080 8083 return rif->dev; 8084 + } 8085 + 8086 + bool mlxsw_sp_rif_has_dev(const struct mlxsw_sp_rif *rif) 8087 + { 8088 + return !!mlxsw_sp_rif_dev(rif); 8089 + } 8090 + 8091 + bool mlxsw_sp_rif_dev_is(const struct mlxsw_sp_rif *rif, 8092 + const struct net_device *dev) 8093 + { 8094 + return mlxsw_sp_rif_dev(rif) == dev; 8081 8095 } 8082 8096 8083 8097 static void mlxsw_sp_rif_push_l3_stats(struct mlxsw_sp_rif *rif) ··· 8887 8879 return notifier_from_errno(err); 8888 8880 } 8889 8881 8890 - int mlxsw_sp_inetaddr_valid_event(struct notifier_block *unused, 8891 - unsigned long event, void *ptr) 8882 + static int mlxsw_sp_inetaddr_valid_event(struct notifier_block *unused, 8883 + unsigned long event, void *ptr) 8892 8884 { 8893 8885 struct in_validator_info *ivi = (struct in_validator_info *) ptr; 8894 8886 struct net_device *dev = ivi->ivi_dev->dev; ··· 8970 8962 return NOTIFY_DONE; 8971 8963 } 8972 8964 8973 - int mlxsw_sp_inet6addr_valid_event(struct notifier_block *unused, 8974 - unsigned long event, void *ptr) 8965 + static int mlxsw_sp_inet6addr_valid_event(struct notifier_block *unused, 8966 + unsigned long event, void *ptr) 8975 8967 { 8976 8968 struct in6_validator_info *i6vi = (struct in6_validator_info *) ptr; 8977 8969 struct net_device *dev = i6vi->i6vi_dev->dev; ··· 10518 10510 struct netlink_ext_ack *extack) 10519 10511 { 10520 10512 struct mlxsw_sp_router *router; 10513 + struct notifier_block *nb; 10521 10514 int err; 10522 10515 10523 10516 router = kzalloc(sizeof(*mlxsw_sp->router), GFP_KERNEL); ··· 10597 10588 if (err) 10598 10589 goto err_register_inet6addr_notifier; 10599 10590 10591 + router->inetaddr_valid_nb.notifier_call = mlxsw_sp_inetaddr_valid_event; 10592 + err = register_inetaddr_validator_notifier(&router->inetaddr_valid_nb); 10593 + if (err) 10594 + goto err_register_inetaddr_valid_notifier; 10595 + 10596 + nb = &router->inet6addr_valid_nb; 10597 + nb->notifier_call = mlxsw_sp_inet6addr_valid_event; 10598 + err = register_inet6addr_validator_notifier(nb); 10599 + if (err) 10600 + goto err_register_inet6addr_valid_notifier; 10601 + 10600 10602 mlxsw_sp->router->netevent_nb.notifier_call = 10601 10603 mlxsw_sp_router_netevent_event; 10602 10604 err = register_netevent_notifier(&mlxsw_sp->router->netevent_nb); ··· 10647 10627 err_register_nexthop_notifier: 10648 10628 unregister_netevent_notifier(&mlxsw_sp->router->netevent_nb); 10649 10629 err_register_netevent_notifier: 10630 + unregister_inet6addr_validator_notifier(&router->inet6addr_valid_nb); 10631 + err_register_inet6addr_valid_notifier: 10632 + unregister_inetaddr_validator_notifier(&router->inetaddr_valid_nb); 10633 + err_register_inetaddr_valid_notifier: 10650 10634 unregister_inet6addr_notifier(&router->inet6addr_nb); 10651 10635 err_register_inet6addr_notifier: 10652 10636 unregister_inetaddr_notifier(&router->inetaddr_nb); ··· 10688 10664 10689 10665 void mlxsw_sp_router_fini(struct mlxsw_sp *mlxsw_sp) 10690 10666 { 10667 + struct mlxsw_sp_router *router = mlxsw_sp->router; 10668 + 10691 10669 unregister_netdevice_notifier_net(mlxsw_sp_net(mlxsw_sp), 10692 - &mlxsw_sp->router->netdevice_nb); 10693 - unregister_fib_notifier(mlxsw_sp_net(mlxsw_sp), 10694 - &mlxsw_sp->router->fib_nb); 10670 + &router->netdevice_nb); 10671 + unregister_fib_notifier(mlxsw_sp_net(mlxsw_sp), &router->fib_nb); 10695 10672 unregister_nexthop_notifier(mlxsw_sp_net(mlxsw_sp), 10696 - &mlxsw_sp->router->nexthop_nb); 10697 - unregister_netevent_notifier(&mlxsw_sp->router->netevent_nb); 10698 - unregister_inet6addr_notifier(&mlxsw_sp->router->inet6addr_nb); 10699 - unregister_inetaddr_notifier(&mlxsw_sp->router->inetaddr_nb); 10673 + &router->nexthop_nb); 10674 + unregister_netevent_notifier(&router->netevent_nb); 10675 + unregister_inet6addr_validator_notifier(&router->inet6addr_valid_nb); 10676 + unregister_inetaddr_validator_notifier(&router->inetaddr_valid_nb); 10677 + unregister_inet6addr_notifier(&router->inet6addr_nb); 10678 + unregister_inetaddr_notifier(&router->inetaddr_nb); 10700 10679 mlxsw_core_flush_owq(); 10701 10680 mlxsw_sp_mp_hash_fini(mlxsw_sp); 10702 10681 mlxsw_sp_neigh_fini(mlxsw_sp); ··· 10707 10680 mlxsw_sp_vrs_fini(mlxsw_sp); 10708 10681 mlxsw_sp_mr_fini(mlxsw_sp); 10709 10682 mlxsw_sp_lpm_fini(mlxsw_sp); 10710 - rhashtable_destroy(&mlxsw_sp->router->nexthop_group_ht); 10711 - rhashtable_destroy(&mlxsw_sp->router->nexthop_ht); 10683 + rhashtable_destroy(&router->nexthop_group_ht); 10684 + rhashtable_destroy(&router->nexthop_ht); 10712 10685 mlxsw_sp_ipips_fini(mlxsw_sp); 10713 10686 mlxsw_sp_rifs_fini(mlxsw_sp); 10714 10687 __mlxsw_sp_router_fini(mlxsw_sp); 10715 - cancel_delayed_work_sync(&mlxsw_sp->router->nh_grp_activity_dw); 10716 - mutex_destroy(&mlxsw_sp->router->lock); 10717 - kfree(mlxsw_sp->router); 10688 + cancel_delayed_work_sync(&router->nh_grp_activity_dw); 10689 + mutex_destroy(&router->lock); 10690 + kfree(router); 10718 10691 }
+5 -1
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h
··· 52 52 struct notifier_block inetaddr_nb; 53 53 struct notifier_block inet6addr_nb; 54 54 struct notifier_block netdevice_nb; 55 + struct notifier_block inetaddr_valid_nb; 56 + struct notifier_block inet6addr_valid_nb; 55 57 const struct mlxsw_sp_rif_ops **rif_ops_arr; 56 58 const struct mlxsw_sp_ipip_ops **ipip_ops_arr; 57 59 struct mlxsw_sp_router_nve_decap nve_decap_config; ··· 93 91 u16 mlxsw_sp_ipip_lb_ul_rif_id(const struct mlxsw_sp_rif_ipip_lb *lb_rif); 94 92 u32 mlxsw_sp_ipip_dev_ul_tb_id(const struct net_device *ol_dev); 95 93 int mlxsw_sp_rif_dev_ifindex(const struct mlxsw_sp_rif *rif); 96 - const struct net_device *mlxsw_sp_rif_dev(const struct mlxsw_sp_rif *rif); 94 + bool mlxsw_sp_rif_has_dev(const struct mlxsw_sp_rif *rif); 95 + bool mlxsw_sp_rif_dev_is(const struct mlxsw_sp_rif *rif, 96 + const struct net_device *dev); 97 97 int mlxsw_sp_rif_counter_value_get(struct mlxsw_sp *mlxsw_sp, 98 98 struct mlxsw_sp_rif *rif, 99 99 enum mlxsw_sp_rif_counter_dir dir,