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

batman-adv: store hard_iface as iflink private data

By passing the hard_iface to netdev_master_upper_dev_link() as private
data, we can iterate over hardifs of a mesh interface more efficiently
using netdev_for_each_lower_private*() (instead of iterating over the
global hardif list). In addition, this will enable resolving a hardif
from its netdev using netdev_lower_dev_get_private() and getting rid of
the global list altogether in the following patches.

A similar approach can be seen in the bonding driver.

Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de>

authored by

Matthias Schiffer and committed by
Simon Wunderlich
7dc28470 2b05db6b

+44 -91
+1
net/batman-adv/bat_algo.c
··· 14 14 #include <linux/skbuff.h> 15 15 #include <linux/stddef.h> 16 16 #include <linux/string.h> 17 + #include <linux/types.h> 17 18 #include <net/genetlink.h> 18 19 #include <net/netlink.h> 19 20 #include <uapi/linux/batman_adv.h>
-2
net/batman-adv/bat_algo.h
··· 11 11 12 12 #include <linux/netlink.h> 13 13 #include <linux/skbuff.h> 14 - #include <linux/types.h> 15 14 16 15 extern char batadv_routing_algo[]; 17 - extern struct list_head batadv_hardif_list; 18 16 19 17 void batadv_algo_init(void); 20 18 struct batadv_algo_ops *batadv_algo_get(const char *name);
+8 -17
net/batman-adv/bat_iv_ogm.c
··· 791 791 struct batadv_ogm_packet *batadv_ogm_packet; 792 792 struct batadv_hard_iface *primary_if, *tmp_hard_iface; 793 793 int *ogm_buff_len = &hard_iface->bat_iv.ogm_buff_len; 794 + struct list_head *iter; 794 795 u32 seqno; 795 796 u16 tvlv_len = 0; 796 797 unsigned long send_time; ··· 848 847 * interfaces. 849 848 */ 850 849 rcu_read_lock(); 851 - list_for_each_entry_rcu(tmp_hard_iface, &batadv_hardif_list, list) { 852 - if (tmp_hard_iface->mesh_iface != hard_iface->mesh_iface) 853 - continue; 854 - 850 + netdev_for_each_lower_private_rcu(hard_iface->mesh_iface, tmp_hard_iface, iter) { 855 851 if (!kref_get_unless_zero(&tmp_hard_iface->refcount)) 856 852 continue; 857 853 ··· 1565 1567 bool is_my_oldorig = false; 1566 1568 bool is_my_addr = false; 1567 1569 bool is_my_orig = false; 1570 + struct list_head *iter; 1568 1571 1569 1572 ogm_packet = (struct batadv_ogm_packet *)(skb->data + ogm_offset); 1570 1573 ethhdr = eth_hdr(skb); ··· 1602 1603 ogm_packet->version, has_directlink_flag); 1603 1604 1604 1605 rcu_read_lock(); 1605 - list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) { 1606 - if (hard_iface->if_status != BATADV_IF_ACTIVE) 1607 - continue; 1608 1606 1609 - if (hard_iface->mesh_iface != if_incoming->mesh_iface) 1607 + netdev_for_each_lower_private_rcu(if_incoming->mesh_iface, hard_iface, iter) { 1608 + if (hard_iface->if_status != BATADV_IF_ACTIVE) 1610 1609 continue; 1611 1610 1612 1611 if (batadv_compare_eth(ethhdr->h_source, ··· 1665 1668 if_incoming, BATADV_IF_DEFAULT); 1666 1669 1667 1670 rcu_read_lock(); 1668 - list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) { 1671 + netdev_for_each_lower_private_rcu(bat_priv->mesh_iface, hard_iface, iter) { 1669 1672 if (hard_iface->if_status != BATADV_IF_ACTIVE) 1670 - continue; 1671 - 1672 - if (hard_iface->mesh_iface != bat_priv->mesh_iface) 1673 1673 continue; 1674 1674 1675 1675 if (!kref_get_unless_zero(&hard_iface->refcount)) ··· 2136 2142 struct batadv_hard_iface *single_hardif) 2137 2143 { 2138 2144 struct batadv_hard_iface *hard_iface; 2145 + struct list_head *iter; 2139 2146 int i_hardif = 0; 2140 2147 int i_hardif_s = cb->args[0]; 2141 2148 int idx = cb->args[1]; ··· 2153 2158 i_hardif++; 2154 2159 } 2155 2160 } else { 2156 - list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, 2157 - list) { 2158 - if (hard_iface->mesh_iface != bat_priv->mesh_iface) 2159 - continue; 2160 - 2161 + netdev_for_each_lower_private_rcu(bat_priv->mesh_iface, hard_iface, iter) { 2161 2162 if (i_hardif++ < i_hardif_s) 2162 2163 continue; 2163 2164
+2 -4
net/batman-adv/bat_v.c
··· 212 212 struct batadv_hard_iface *single_hardif) 213 213 { 214 214 struct batadv_hard_iface *hard_iface; 215 + struct list_head *iter; 215 216 int i_hardif = 0; 216 217 int i_hardif_s = cb->args[0]; 217 218 int idx = cb->args[1]; ··· 228 227 i_hardif++; 229 228 } 230 229 } else { 231 - list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) { 232 - if (hard_iface->mesh_iface != bat_priv->mesh_iface) 233 - continue; 234 - 230 + netdev_for_each_lower_private_rcu(bat_priv->mesh_iface, hard_iface, iter) { 235 231 if (i_hardif++ < i_hardif_s) 236 232 continue; 237 233
+2 -6
net/batman-adv/bat_v_elp.c
··· 35 35 #include <net/cfg80211.h> 36 36 #include <uapi/linux/batadv_packet.h> 37 37 38 - #include "bat_algo.h" 39 38 #include "bat_v_ogm.h" 40 39 #include "hard-interface.h" 41 40 #include "log.h" ··· 471 472 void batadv_v_elp_primary_iface_set(struct batadv_hard_iface *primary_iface) 472 473 { 473 474 struct batadv_hard_iface *hard_iface; 475 + struct list_head *iter; 474 476 475 477 /* update orig field of every elp iface belonging to this mesh */ 476 478 rcu_read_lock(); 477 - list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) { 478 - if (primary_iface->mesh_iface != hard_iface->mesh_iface) 479 - continue; 480 - 479 + netdev_for_each_lower_private_rcu(primary_iface->mesh_iface, hard_iface, iter) 481 480 batadv_v_elp_iface_activate(primary_iface, hard_iface); 482 - } 483 481 rcu_read_unlock(); 484 482 } 485 483
+4 -10
net/batman-adv/bat_v_ogm.c
··· 22 22 #include <linux/mutex.h> 23 23 #include <linux/netdevice.h> 24 24 #include <linux/random.h> 25 - #include <linux/rculist.h> 26 25 #include <linux/rcupdate.h> 27 26 #include <linux/skbuff.h> 28 27 #include <linux/slab.h> ··· 32 33 #include <linux/workqueue.h> 33 34 #include <uapi/linux/batadv_packet.h> 34 35 35 - #include "bat_algo.h" 36 36 #include "hard-interface.h" 37 37 #include "hash.h" 38 38 #include "log.h" ··· 263 265 struct batadv_ogm2_packet *ogm_packet; 264 266 struct sk_buff *skb, *skb_tmp; 265 267 unsigned char *ogm_buff; 268 + struct list_head *iter; 266 269 int ogm_buff_len; 267 270 u16 tvlv_len = 0; 268 271 int ret; ··· 300 301 301 302 /* broadcast on every interface */ 302 303 rcu_read_lock(); 303 - list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) { 304 - if (hard_iface->mesh_iface != bat_priv->mesh_iface) 305 - continue; 306 - 304 + netdev_for_each_lower_private_rcu(bat_priv->mesh_iface, hard_iface, iter) { 307 305 if (!kref_get_unless_zero(&hard_iface->refcount)) 308 306 continue; 309 307 ··· 855 859 struct batadv_hard_iface *hard_iface; 856 860 struct batadv_ogm2_packet *ogm_packet; 857 861 u32 ogm_throughput, link_throughput, path_throughput; 862 + struct list_head *iter; 858 863 int ret; 859 864 860 865 ethhdr = eth_hdr(skb); ··· 918 921 BATADV_IF_DEFAULT); 919 922 920 923 rcu_read_lock(); 921 - list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) { 924 + netdev_for_each_lower_private_rcu(bat_priv->mesh_iface, hard_iface, iter) { 922 925 if (hard_iface->if_status != BATADV_IF_ACTIVE) 923 - continue; 924 - 925 - if (hard_iface->mesh_iface != bat_priv->mesh_iface) 926 926 continue; 927 927 928 928 if (!kref_get_unless_zero(&hard_iface->refcount))
+14 -25
net/batman-adv/hard-interface.c
··· 438 438 } 439 439 440 440 static struct batadv_hard_iface * 441 - batadv_hardif_get_active(const struct net_device *mesh_iface) 441 + batadv_hardif_get_active(struct net_device *mesh_iface) 442 442 { 443 443 struct batadv_hard_iface *hard_iface; 444 + struct list_head *iter; 444 445 445 446 rcu_read_lock(); 446 - list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) { 447 - if (hard_iface->mesh_iface != mesh_iface) 448 - continue; 449 - 447 + netdev_for_each_lower_private_rcu(mesh_iface, hard_iface, iter) { 450 448 if (hard_iface->if_status == BATADV_IF_ACTIVE && 451 449 kref_get_unless_zero(&hard_iface->refcount)) 452 450 goto out; ··· 506 508 507 509 static void batadv_check_known_mac_addr(const struct batadv_hard_iface *hard_iface) 508 510 { 509 - const struct net_device *mesh_iface = hard_iface->mesh_iface; 511 + struct net_device *mesh_iface = hard_iface->mesh_iface; 510 512 const struct batadv_hard_iface *tmp_hard_iface; 513 + struct list_head *iter; 511 514 512 515 if (!mesh_iface) 513 516 return; 514 517 515 - list_for_each_entry(tmp_hard_iface, &batadv_hardif_list, list) { 518 + netdev_for_each_lower_private(mesh_iface, tmp_hard_iface, iter) { 516 519 if (tmp_hard_iface == hard_iface) 517 - continue; 518 - 519 - if (tmp_hard_iface->mesh_iface != mesh_iface) 520 520 continue; 521 521 522 522 if (tmp_hard_iface->if_status == BATADV_IF_NOT_IN_USE) ··· 541 545 unsigned short lower_headroom = 0; 542 546 unsigned short lower_tailroom = 0; 543 547 unsigned short needed_headroom; 548 + struct list_head *iter; 544 549 545 550 rcu_read_lock(); 546 - list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) { 551 + netdev_for_each_lower_private_rcu(mesh_iface, hard_iface, iter) { 547 552 if (hard_iface->if_status == BATADV_IF_NOT_IN_USE) 548 - continue; 549 - 550 - if (hard_iface->mesh_iface != mesh_iface) 551 553 continue; 552 554 553 555 lower_header_len = max_t(unsigned short, lower_header_len, ··· 580 586 { 581 587 struct batadv_priv *bat_priv = netdev_priv(mesh_iface); 582 588 const struct batadv_hard_iface *hard_iface; 589 + struct list_head *iter; 583 590 int min_mtu = INT_MAX; 584 591 585 592 rcu_read_lock(); 586 - list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) { 593 + netdev_for_each_lower_private_rcu(mesh_iface, hard_iface, iter) { 587 594 if (hard_iface->if_status != BATADV_IF_ACTIVE && 588 595 hard_iface->if_status != BATADV_IF_TO_BE_ACTIVATED) 589 - continue; 590 - 591 - if (hard_iface->mesh_iface != mesh_iface) 592 596 continue; 593 597 594 598 min_mtu = min_t(int, hard_iface->net_dev->mtu, min_mtu); ··· 726 734 bat_priv = netdev_priv(hard_iface->mesh_iface); 727 735 728 736 ret = netdev_master_upper_dev_link(hard_iface->net_dev, 729 - mesh_iface, NULL, NULL, NULL); 737 + mesh_iface, hard_iface, NULL, NULL); 730 738 if (ret) 731 739 goto err_dev; 732 740 ··· 795 803 * 796 804 * Return: number of connected/enslaved hard interfaces 797 805 */ 798 - static size_t batadv_hardif_cnt(const struct net_device *mesh_iface) 806 + static size_t batadv_hardif_cnt(struct net_device *mesh_iface) 799 807 { 800 808 struct batadv_hard_iface *hard_iface; 809 + struct list_head *iter; 801 810 size_t count = 0; 802 811 803 812 rcu_read_lock(); 804 - list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) { 805 - if (hard_iface->mesh_iface != mesh_iface) 806 - continue; 807 - 813 + netdev_for_each_lower_private_rcu(mesh_iface, hard_iface, iter) 808 814 count++; 809 - } 810 815 rcu_read_unlock(); 811 816 812 817 return count;
+2 -5
net/batman-adv/main.c
··· 27 27 #include <linux/module.h> 28 28 #include <linux/netdevice.h> 29 29 #include <linux/printk.h> 30 - #include <linux/rculist.h> 31 30 #include <linux/rcupdate.h> 32 31 #include <linux/skbuff.h> 33 32 #include <linux/slab.h> ··· 302 303 bool batadv_is_my_mac(struct batadv_priv *bat_priv, const u8 *addr) 303 304 { 304 305 const struct batadv_hard_iface *hard_iface; 306 + struct list_head *iter; 305 307 bool is_my_mac = false; 306 308 307 309 rcu_read_lock(); 308 - list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) { 310 + netdev_for_each_lower_private_rcu(bat_priv->mesh_iface, hard_iface, iter) { 309 311 if (hard_iface->if_status != BATADV_IF_ACTIVE) 310 - continue; 311 - 312 - if (hard_iface->mesh_iface != bat_priv->mesh_iface) 313 312 continue; 314 313 315 314 if (batadv_compare_eth(hard_iface->net_dev->dev_addr, addr)) {
+3 -3
net/batman-adv/mesh-interface.c
··· 1101 1101 struct batadv_hard_iface *hard_iface; 1102 1102 struct batadv_meshif_vlan *vlan; 1103 1103 1104 - list_for_each_entry(hard_iface, &batadv_hardif_list, list) { 1105 - if (hard_iface->mesh_iface == mesh_iface) 1106 - batadv_hardif_disable_interface(hard_iface); 1104 + while (!list_empty(&mesh_iface->adj_list.lower)) { 1105 + hard_iface = netdev_adjacent_get_private(mesh_iface->adj_list.lower.next); 1106 + batadv_hardif_disable_interface(hard_iface); 1107 1107 } 1108 1108 1109 1109 /* destroy the "untagged" VLAN */
+2 -4
net/batman-adv/multicast.c
··· 246 246 static u8 batadv_mcast_mla_forw_flags_get(struct batadv_priv *bat_priv) 247 247 { 248 248 const struct batadv_hard_iface *hard_iface; 249 + struct list_head *iter; 249 250 250 251 rcu_read_lock(); 251 - list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) { 252 + netdev_for_each_lower_private_rcu(bat_priv->mesh_iface, hard_iface, iter) { 252 253 if (hard_iface->if_status != BATADV_IF_ACTIVE) 253 - continue; 254 - 255 - if (hard_iface->mesh_iface != bat_priv->mesh_iface) 256 254 continue; 257 255 258 256 if (hard_iface->net_dev->mtu < IPV6_MIN_MTU) {
+2 -5
net/batman-adv/netlink.c
··· 20 20 #include <linux/if_vlan.h> 21 21 #include <linux/init.h> 22 22 #include <linux/limits.h> 23 - #include <linux/list.h> 24 23 #include <linux/minmax.h> 25 24 #include <linux/netdevice.h> 26 25 #include <linux/netlink.h> ··· 967 968 struct batadv_priv *bat_priv; 968 969 int portid = NETLINK_CB(cb->skb).portid; 969 970 int skip = cb->args[0]; 971 + struct list_head *iter; 970 972 int i = 0; 971 973 972 974 mesh_iface = batadv_netlink_get_meshif(cb); ··· 979 979 rtnl_lock(); 980 980 cb->seq = batadv_hardif_generation << 1 | 1; 981 981 982 - list_for_each_entry(hard_iface, &batadv_hardif_list, list) { 983 - if (hard_iface->mesh_iface != mesh_iface) 984 - continue; 985 - 982 + netdev_for_each_lower_private(mesh_iface, hard_iface, iter) { 986 983 if (i++ < skip) 987 984 continue; 988 985
+2 -5
net/batman-adv/originator.c
··· 29 29 #include <linux/workqueue.h> 30 30 #include <uapi/linux/batadv_packet.h> 31 31 32 - #include "bat_algo.h" 33 32 #include "distributed-arp-table.h" 34 33 #include "fragmentation.h" 35 34 #include "gateway_client.h" ··· 1207 1208 struct batadv_neigh_node *best_neigh_node; 1208 1209 struct batadv_hard_iface *hard_iface; 1209 1210 bool changed_ifinfo, changed_neigh; 1211 + struct list_head *iter; 1210 1212 1211 1213 if (batadv_has_timed_out(orig_node->last_seen, 1212 1214 2 * BATADV_PURGE_TIMEOUT)) { ··· 1232 1232 1233 1233 /* ... then for all other interfaces. */ 1234 1234 rcu_read_lock(); 1235 - list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) { 1235 + netdev_for_each_lower_private_rcu(bat_priv->mesh_iface, hard_iface, iter) { 1236 1236 if (hard_iface->if_status != BATADV_IF_ACTIVE) 1237 - continue; 1238 - 1239 - if (hard_iface->mesh_iface != bat_priv->mesh_iface) 1240 1237 continue; 1241 1238 1242 1239 if (!kref_get_unless_zero(&hard_iface->refcount))
+2 -5
net/batman-adv/send.c
··· 21 21 #include <linux/list.h> 22 22 #include <linux/netdevice.h> 23 23 #include <linux/printk.h> 24 - #include <linux/rculist.h> 25 24 #include <linux/rcupdate.h> 26 25 #include <linux/skbuff.h> 27 26 #include <linux/slab.h> ··· 923 924 { 924 925 struct batadv_hard_iface *hard_iface; 925 926 struct batadv_hard_iface *primary_if; 927 + struct list_head *iter; 926 928 int ret = NETDEV_TX_OK; 927 929 928 930 primary_if = batadv_primary_if_get_selected(bat_priv); ··· 931 931 return NETDEV_TX_BUSY; 932 932 933 933 rcu_read_lock(); 934 - list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) { 935 - if (hard_iface->mesh_iface != bat_priv->mesh_iface) 936 - continue; 937 - 934 + netdev_for_each_lower_private_rcu(bat_priv->mesh_iface, hard_iface, iter) { 938 935 if (!kref_get_unless_zero(&hard_iface->refcount)) 939 936 continue; 940 937