diff options
author | Eric Dumazet <eric.dumazet@gmail.com> | 2009-09-01 02:31:18 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-09-01 20:40:26 -0400 |
commit | 885a136c52a8871175477baf3903e1c38751b35a (patch) | |
tree | 7df36a899371078e1600531d4c6e3870e188cd60 | |
parent | ac06713d55d450cbc9ef871b1b238409238f0fe0 (diff) |
bonding: use compare_ether_addr_64bits() in ALB
We can speedup ether addresses compares using compare_ether_addr_64bits()
instead of memcmp(). We make sure all operands are at least 8 bytes long and
16bits aligned (or better, long word aligned if possible)
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Reviewed-by: Jiri Pirko <jpirko@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/bonding/bond_alb.c | 71 | ||||
-rw-r--r-- | drivers/net/bonding/bonding.h | 2 |
2 files changed, 38 insertions, 35 deletions
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index 2108706d2f0c..9b5936f072dc 100644 --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c | |||
@@ -79,8 +79,15 @@ | |||
79 | */ | 79 | */ |
80 | #define RLB_PROMISC_TIMEOUT 10*ALB_TIMER_TICKS_PER_SEC | 80 | #define RLB_PROMISC_TIMEOUT 10*ALB_TIMER_TICKS_PER_SEC |
81 | 81 | ||
82 | static const u8 mac_bcast[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff}; | 82 | #ifndef __long_aligned |
83 | static const u8 mac_v6_allmcast[ETH_ALEN] = {0x33,0x33,0x00,0x00,0x00,0x01}; | 83 | #define __long_aligned __attribute__((aligned((sizeof(long))))) |
84 | #endif | ||
85 | static const u8 mac_bcast[ETH_ALEN] __long_aligned = { | ||
86 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff | ||
87 | }; | ||
88 | static const u8 mac_v6_allmcast[ETH_ALEN] __long_aligned = { | ||
89 | 0x33, 0x33, 0x00, 0x00, 0x00, 0x01 | ||
90 | }; | ||
84 | static const int alb_delta_in_ticks = HZ / ALB_TIMER_TICKS_PER_SEC; | 91 | static const int alb_delta_in_ticks = HZ / ALB_TIMER_TICKS_PER_SEC; |
85 | 92 | ||
86 | #pragma pack(1) | 93 | #pragma pack(1) |
@@ -460,8 +467,8 @@ static void rlb_clear_slave(struct bonding *bond, struct slave *slave) | |||
460 | 467 | ||
461 | if (assigned_slave) { | 468 | if (assigned_slave) { |
462 | rx_hash_table[index].slave = assigned_slave; | 469 | rx_hash_table[index].slave = assigned_slave; |
463 | if (memcmp(rx_hash_table[index].mac_dst, | 470 | if (compare_ether_addr_64bits(rx_hash_table[index].mac_dst, |
464 | mac_bcast, ETH_ALEN)) { | 471 | mac_bcast)) { |
465 | bond_info->rx_hashtbl[index].ntt = 1; | 472 | bond_info->rx_hashtbl[index].ntt = 1; |
466 | bond_info->rx_ntt = 1; | 473 | bond_info->rx_ntt = 1; |
467 | /* A slave has been removed from the | 474 | /* A slave has been removed from the |
@@ -575,7 +582,7 @@ static void rlb_req_update_slave_clients(struct bonding *bond, struct slave *sla | |||
575 | client_info = &(bond_info->rx_hashtbl[hash_index]); | 582 | client_info = &(bond_info->rx_hashtbl[hash_index]); |
576 | 583 | ||
577 | if ((client_info->slave == slave) && | 584 | if ((client_info->slave == slave) && |
578 | memcmp(client_info->mac_dst, mac_bcast, ETH_ALEN)) { | 585 | compare_ether_addr_64bits(client_info->mac_dst, mac_bcast)) { |
579 | client_info->ntt = 1; | 586 | client_info->ntt = 1; |
580 | ntt = 1; | 587 | ntt = 1; |
581 | } | 588 | } |
@@ -616,9 +623,9 @@ static void rlb_req_update_subnet_clients(struct bonding *bond, __be32 src_ip) | |||
616 | * unicast mac address. | 623 | * unicast mac address. |
617 | */ | 624 | */ |
618 | if ((client_info->ip_src == src_ip) && | 625 | if ((client_info->ip_src == src_ip) && |
619 | memcmp(client_info->slave->dev->dev_addr, | 626 | compare_ether_addr_64bits(client_info->slave->dev->dev_addr, |
620 | bond->dev->dev_addr, ETH_ALEN) && | 627 | bond->dev->dev_addr) && |
621 | memcmp(client_info->mac_dst, mac_bcast, ETH_ALEN)) { | 628 | compare_ether_addr_64bits(client_info->mac_dst, mac_bcast)) { |
622 | client_info->ntt = 1; | 629 | client_info->ntt = 1; |
623 | bond_info->rx_ntt = 1; | 630 | bond_info->rx_ntt = 1; |
624 | } | 631 | } |
@@ -645,7 +652,7 @@ static struct slave *rlb_choose_channel(struct sk_buff *skb, struct bonding *bon | |||
645 | if ((client_info->ip_src == arp->ip_src) && | 652 | if ((client_info->ip_src == arp->ip_src) && |
646 | (client_info->ip_dst == arp->ip_dst)) { | 653 | (client_info->ip_dst == arp->ip_dst)) { |
647 | /* the entry is already assigned to this client */ | 654 | /* the entry is already assigned to this client */ |
648 | if (memcmp(arp->mac_dst, mac_bcast, ETH_ALEN)) { | 655 | if (compare_ether_addr_64bits(arp->mac_dst, mac_bcast)) { |
649 | /* update mac address from arp */ | 656 | /* update mac address from arp */ |
650 | memcpy(client_info->mac_dst, arp->mac_dst, ETH_ALEN); | 657 | memcpy(client_info->mac_dst, arp->mac_dst, ETH_ALEN); |
651 | } | 658 | } |
@@ -680,7 +687,7 @@ static struct slave *rlb_choose_channel(struct sk_buff *skb, struct bonding *bon | |||
680 | memcpy(client_info->mac_dst, arp->mac_dst, ETH_ALEN); | 687 | memcpy(client_info->mac_dst, arp->mac_dst, ETH_ALEN); |
681 | client_info->slave = assigned_slave; | 688 | client_info->slave = assigned_slave; |
682 | 689 | ||
683 | if (memcmp(client_info->mac_dst, mac_bcast, ETH_ALEN)) { | 690 | if (compare_ether_addr_64bits(client_info->mac_dst, mac_bcast)) { |
684 | client_info->ntt = 1; | 691 | client_info->ntt = 1; |
685 | bond->alb_info.rx_ntt = 1; | 692 | bond->alb_info.rx_ntt = 1; |
686 | } else { | 693 | } else { |
@@ -1046,21 +1053,18 @@ static void alb_change_hw_addr_on_detach(struct bonding *bond, struct slave *sla | |||
1046 | int perm_curr_diff; | 1053 | int perm_curr_diff; |
1047 | int perm_bond_diff; | 1054 | int perm_bond_diff; |
1048 | 1055 | ||
1049 | perm_curr_diff = memcmp(slave->perm_hwaddr, | 1056 | perm_curr_diff = compare_ether_addr_64bits(slave->perm_hwaddr, |
1050 | slave->dev->dev_addr, | 1057 | slave->dev->dev_addr); |
1051 | ETH_ALEN); | 1058 | perm_bond_diff = compare_ether_addr_64bits(slave->perm_hwaddr, |
1052 | perm_bond_diff = memcmp(slave->perm_hwaddr, | 1059 | bond->dev->dev_addr); |
1053 | bond->dev->dev_addr, | ||
1054 | ETH_ALEN); | ||
1055 | 1060 | ||
1056 | if (perm_curr_diff && perm_bond_diff) { | 1061 | if (perm_curr_diff && perm_bond_diff) { |
1057 | struct slave *tmp_slave; | 1062 | struct slave *tmp_slave; |
1058 | int i, found = 0; | 1063 | int i, found = 0; |
1059 | 1064 | ||
1060 | bond_for_each_slave(bond, tmp_slave, i) { | 1065 | bond_for_each_slave(bond, tmp_slave, i) { |
1061 | if (!memcmp(slave->perm_hwaddr, | 1066 | if (!compare_ether_addr_64bits(slave->perm_hwaddr, |
1062 | tmp_slave->dev->dev_addr, | 1067 | tmp_slave->dev->dev_addr)) { |
1063 | ETH_ALEN)) { | ||
1064 | found = 1; | 1068 | found = 1; |
1065 | break; | 1069 | break; |
1066 | } | 1070 | } |
@@ -1114,10 +1118,10 @@ static int alb_handle_addr_collision_on_attach(struct bonding *bond, struct slav | |||
1114 | * check uniqueness of slave's mac address against the other | 1118 | * check uniqueness of slave's mac address against the other |
1115 | * slaves in the bond. | 1119 | * slaves in the bond. |
1116 | */ | 1120 | */ |
1117 | if (memcmp(slave->perm_hwaddr, bond->dev->dev_addr, ETH_ALEN)) { | 1121 | if (compare_ether_addr_64bits(slave->perm_hwaddr, bond->dev->dev_addr)) { |
1118 | bond_for_each_slave(bond, tmp_slave1, i) { | 1122 | bond_for_each_slave(bond, tmp_slave1, i) { |
1119 | if (!memcmp(tmp_slave1->dev->dev_addr, slave->dev->dev_addr, | 1123 | if (!compare_ether_addr_64bits(tmp_slave1->dev->dev_addr, |
1120 | ETH_ALEN)) { | 1124 | slave->dev->dev_addr)) { |
1121 | found = 1; | 1125 | found = 1; |
1122 | break; | 1126 | break; |
1123 | } | 1127 | } |
@@ -1140,9 +1144,8 @@ static int alb_handle_addr_collision_on_attach(struct bonding *bond, struct slav | |||
1140 | bond_for_each_slave(bond, tmp_slave1, i) { | 1144 | bond_for_each_slave(bond, tmp_slave1, i) { |
1141 | found = 0; | 1145 | found = 0; |
1142 | bond_for_each_slave(bond, tmp_slave2, j) { | 1146 | bond_for_each_slave(bond, tmp_slave2, j) { |
1143 | if (!memcmp(tmp_slave1->perm_hwaddr, | 1147 | if (!compare_ether_addr_64bits(tmp_slave1->perm_hwaddr, |
1144 | tmp_slave2->dev->dev_addr, | 1148 | tmp_slave2->dev->dev_addr)) { |
1145 | ETH_ALEN)) { | ||
1146 | found = 1; | 1149 | found = 1; |
1147 | break; | 1150 | break; |
1148 | } | 1151 | } |
@@ -1157,9 +1160,8 @@ static int alb_handle_addr_collision_on_attach(struct bonding *bond, struct slav | |||
1157 | } | 1160 | } |
1158 | 1161 | ||
1159 | if (!has_bond_addr) { | 1162 | if (!has_bond_addr) { |
1160 | if (!memcmp(tmp_slave1->dev->dev_addr, | 1163 | if (!compare_ether_addr_64bits(tmp_slave1->dev->dev_addr, |
1161 | bond->dev->dev_addr, | 1164 | bond->dev->dev_addr)) { |
1162 | ETH_ALEN)) { | ||
1163 | 1165 | ||
1164 | has_bond_addr = tmp_slave1; | 1166 | has_bond_addr = tmp_slave1; |
1165 | } | 1167 | } |
@@ -1313,7 +1315,7 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev) | |||
1313 | case ETH_P_IP: { | 1315 | case ETH_P_IP: { |
1314 | const struct iphdr *iph = ip_hdr(skb); | 1316 | const struct iphdr *iph = ip_hdr(skb); |
1315 | 1317 | ||
1316 | if ((memcmp(eth_data->h_dest, mac_bcast, ETH_ALEN) == 0) || | 1318 | if (!compare_ether_addr_64bits(eth_data->h_dest, mac_bcast) || |
1317 | (iph->daddr == ip_bcast) || | 1319 | (iph->daddr == ip_bcast) || |
1318 | (iph->protocol == IPPROTO_IGMP)) { | 1320 | (iph->protocol == IPPROTO_IGMP)) { |
1319 | do_tx_balance = 0; | 1321 | do_tx_balance = 0; |
@@ -1327,7 +1329,7 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev) | |||
1327 | /* IPv6 doesn't really use broadcast mac address, but leave | 1329 | /* IPv6 doesn't really use broadcast mac address, but leave |
1328 | * that here just in case. | 1330 | * that here just in case. |
1329 | */ | 1331 | */ |
1330 | if (memcmp(eth_data->h_dest, mac_bcast, ETH_ALEN) == 0) { | 1332 | if (!compare_ether_addr_64bits(eth_data->h_dest, mac_bcast)) { |
1331 | do_tx_balance = 0; | 1333 | do_tx_balance = 0; |
1332 | break; | 1334 | break; |
1333 | } | 1335 | } |
@@ -1335,7 +1337,7 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev) | |||
1335 | /* IPv6 uses all-nodes multicast as an equivalent to | 1337 | /* IPv6 uses all-nodes multicast as an equivalent to |
1336 | * broadcasts in IPv4. | 1338 | * broadcasts in IPv4. |
1337 | */ | 1339 | */ |
1338 | if (memcmp(eth_data->h_dest, mac_v6_allmcast, ETH_ALEN) == 0) { | 1340 | if (!compare_ether_addr_64bits(eth_data->h_dest, mac_v6_allmcast)) { |
1339 | do_tx_balance = 0; | 1341 | do_tx_balance = 0; |
1340 | break; | 1342 | break; |
1341 | } | 1343 | } |
@@ -1660,8 +1662,8 @@ void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave | |||
1660 | struct slave *tmp_slave; | 1662 | struct slave *tmp_slave; |
1661 | /* find slave that is holding the bond's mac address */ | 1663 | /* find slave that is holding the bond's mac address */ |
1662 | bond_for_each_slave(bond, tmp_slave, i) { | 1664 | bond_for_each_slave(bond, tmp_slave, i) { |
1663 | if (!memcmp(tmp_slave->dev->dev_addr, | 1665 | if (!compare_ether_addr_64bits(tmp_slave->dev->dev_addr, |
1664 | bond->dev->dev_addr, ETH_ALEN)) { | 1666 | bond->dev->dev_addr)) { |
1665 | swap_slave = tmp_slave; | 1667 | swap_slave = tmp_slave; |
1666 | break; | 1668 | break; |
1667 | } | 1669 | } |
@@ -1739,7 +1741,8 @@ int bond_alb_set_mac_address(struct net_device *bond_dev, void *addr) | |||
1739 | swap_slave = NULL; | 1741 | swap_slave = NULL; |
1740 | 1742 | ||
1741 | bond_for_each_slave(bond, slave, i) { | 1743 | bond_for_each_slave(bond, slave, i) { |
1742 | if (!memcmp(slave->dev->dev_addr, bond_dev->dev_addr, ETH_ALEN)) { | 1744 | if (!compare_ether_addr_64bits(slave->dev->dev_addr, |
1745 | bond_dev->dev_addr)) { | ||
1743 | swap_slave = slave; | 1746 | swap_slave = slave; |
1744 | break; | 1747 | break; |
1745 | } | 1748 | } |
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index 6290a502742e..68247714466f 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h | |||
@@ -163,9 +163,9 @@ struct slave { | |||
163 | u32 original_flags; | 163 | u32 original_flags; |
164 | u32 original_mtu; | 164 | u32 original_mtu; |
165 | u32 link_failure_count; | 165 | u32 link_failure_count; |
166 | u8 perm_hwaddr[ETH_ALEN]; | ||
166 | u16 speed; | 167 | u16 speed; |
167 | u8 duplex; | 168 | u8 duplex; |
168 | u8 perm_hwaddr[ETH_ALEN]; | ||
169 | struct ad_slave_info ad_info; /* HUGE - better to dynamically alloc */ | 169 | struct ad_slave_info ad_info; /* HUGE - better to dynamically alloc */ |
170 | struct tlb_slave_info tlb_info; | 170 | struct tlb_slave_info tlb_info; |
171 | }; | 171 | }; |