From: Nora Schiffer With interfaces being kept track of as iflink private data, there is no need for the global list anymore. batadv_hardif_get_by_netdev() can now use netdev_master_upper_dev_get()+netdev_lower_dev_get_private() to find the hardif corresponding to a netdev. Signed-off-by: Nora Schiffer Signed-off-by: Sven Eckelmann Signed-off-by: Simon Wunderlich --- net/batman-adv/hard-interface.c | 29 ++++++++++++----------------- net/batman-adv/hard-interface.h | 2 +- net/batman-adv/main.c | 5 ----- net/batman-adv/main.h | 1 - net/batman-adv/netlink.c | 2 ++ net/batman-adv/types.h | 3 --- 6 files changed, 15 insertions(+), 27 deletions(-) diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c index 9c9a892d22c6b..ace81348ddef7 100644 --- a/net/batman-adv/hard-interface.c +++ b/net/batman-adv/hard-interface.c @@ -75,21 +75,21 @@ void batadv_hardif_release(struct kref *ref) * Return: batadv_hard_iface of net_dev (with increased refcnt), NULL on errors */ struct batadv_hard_iface * -batadv_hardif_get_by_netdev(const struct net_device *net_dev) +batadv_hardif_get_by_netdev(struct net_device *net_dev) { struct batadv_hard_iface *hard_iface; + struct net_device *mesh_iface; - rcu_read_lock(); - list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) { - if (hard_iface->net_dev == net_dev && - kref_get_unless_zero(&hard_iface->refcount)) - goto out; - } + ASSERT_RTNL(); - hard_iface = NULL; + mesh_iface = netdev_master_upper_dev_get(net_dev); + if (!mesh_iface || !batadv_meshif_is_valid(mesh_iface)) + return NULL; + + hard_iface = netdev_lower_dev_get_private(mesh_iface, net_dev); + if (!kref_get_unless_zero(&hard_iface->refcount)) + return NULL; -out: - rcu_read_unlock(); return hard_iface; } @@ -761,7 +761,6 @@ int batadv_hardif_enable_interface(struct net_device *net_dev, hard_iface->if_status = BATADV_IF_INACTIVE; - INIT_LIST_HEAD(&hard_iface->list); INIT_HLIST_HEAD(&hard_iface->neigh_list); mutex_init(&hard_iface->bat_iv.ogm_buff_mutex); @@ -780,6 +779,7 @@ int batadv_hardif_enable_interface(struct net_device *net_dev, hard_iface->mesh_iface = mesh_iface; bat_priv = netdev_priv(hard_iface->mesh_iface); + batadv_hardif_generation++; ret = netdev_master_upper_dev_link(hard_iface->net_dev, mesh_iface, hard_iface, NULL, NULL); if (ret) @@ -824,9 +824,6 @@ int batadv_hardif_enable_interface(struct net_device *net_dev, if (bat_priv->algo_ops->iface.enabled) bat_priv->algo_ops->iface.enabled(hard_iface); - list_add_tail_rcu(&hard_iface->list, &batadv_hardif_list); - batadv_hardif_generation++; - return 0; err_upper: @@ -854,9 +851,6 @@ void batadv_hardif_disable_interface(struct batadv_hard_iface *hard_iface) if (hard_iface->if_status != BATADV_IF_INACTIVE) goto out; - list_del_rcu(&hard_iface->list); - batadv_hardif_generation++; - batadv_info(hard_iface->mesh_iface, "Removing interface: %s\n", hard_iface->net_dev->name); dev_remove_pack(&hard_iface->batman_adv_ptype); @@ -879,6 +873,7 @@ void batadv_hardif_disable_interface(struct batadv_hard_iface *hard_iface) batadv_purge_outstanding_packets(bat_priv, hard_iface); netdev_put(hard_iface->mesh_iface, &hard_iface->meshif_dev_tracker); + batadv_hardif_generation++; netdev_upper_dev_unlink(hard_iface->net_dev, hard_iface->mesh_iface); batadv_hardif_recalc_extra_skbroom(hard_iface->mesh_iface); diff --git a/net/batman-adv/hard-interface.h b/net/batman-adv/hard-interface.h index 6d72dbdd5c203..aa9275dec0976 100644 --- a/net/batman-adv/hard-interface.h +++ b/net/batman-adv/hard-interface.h @@ -74,7 +74,7 @@ u32 batadv_netdev_get_wifi_flags(struct net_device *net_dev); u32 batadv_hardif_get_wifi_flags(struct batadv_hard_iface *hard_iface); bool batadv_is_wifi_hardif(struct batadv_hard_iface *hard_iface); struct batadv_hard_iface* -batadv_hardif_get_by_netdev(const struct net_device *net_dev); +batadv_hardif_get_by_netdev(struct net_device *net_dev); int batadv_hardif_enable_interface(struct net_device *net_dev, struct net_device *mesh_iface); void batadv_hardif_disable_interface(struct batadv_hard_iface *hard_iface); diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c index 3c4572284b532..1d82f3a841a1b 100644 --- a/net/batman-adv/main.c +++ b/net/batman-adv/main.c @@ -59,10 +59,6 @@ #include "tp_meter.h" #include "translation-table.h" -/* List manipulations on hardif_list have to be rtnl_lock()'ed, - * list traversals just rcu-locked - */ -struct list_head batadv_hardif_list; unsigned int batadv_hardif_generation; static int (*batadv_rx_handler[256])(struct sk_buff *skb, struct batadv_hard_iface *recv_if); @@ -95,7 +91,6 @@ static int __init batadv_init(void) if (ret < 0) return ret; - INIT_LIST_HEAD(&batadv_hardif_list); batadv_algo_init(); batadv_recv_handler_init(); diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h index f68fc8b7239cd..e34145047a341 100644 --- a/net/batman-adv/main.h +++ b/net/batman-adv/main.h @@ -226,7 +226,6 @@ static inline int batadv_print_vid(unsigned short vid) return -1; } -extern struct list_head batadv_hardif_list; extern unsigned int batadv_hardif_generation; extern struct workqueue_struct *batadv_event_workqueue; diff --git a/net/batman-adv/netlink.c b/net/batman-adv/netlink.c index 4cf9e3c54ad3b..62ea91aa3ead6 100644 --- a/net/batman-adv/netlink.c +++ b/net/batman-adv/netlink.c @@ -1211,7 +1211,9 @@ batadv_netlink_get_hardif_from_ifindex(struct batadv_priv *bat_priv, if (!hard_dev) return ERR_PTR(-ENODEV); + rtnl_lock(); hard_iface = batadv_hardif_get_by_netdev(hard_dev); + rtnl_unlock(); if (!hard_iface) goto err_put_harddev; diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h index b1f9f8964c3fd..1671380b37929 100644 --- a/net/batman-adv/types.h +++ b/net/batman-adv/types.h @@ -214,9 +214,6 @@ struct batadv_wifi_net_device_state { * struct batadv_hard_iface - network device known to batman-adv */ struct batadv_hard_iface { - /** @list: list node for batadv_hardif_list */ - struct list_head list; - /** @if_status: status of the interface for batman-adv */ char if_status; -- 2.47.3