mirror of https://gitee.com/openkylin/linux.git
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>
This commit is contained in:
parent
ac06713d55
commit
885a136c52
|
@ -79,8 +79,15 @@
|
||||||
*/
|
*/
|
||||||
#define RLB_PROMISC_TIMEOUT 10*ALB_TIMER_TICKS_PER_SEC
|
#define RLB_PROMISC_TIMEOUT 10*ALB_TIMER_TICKS_PER_SEC
|
||||||
|
|
||||||
static const u8 mac_bcast[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
|
#ifndef __long_aligned
|
||||||
static const u8 mac_v6_allmcast[ETH_ALEN] = {0x33,0x33,0x00,0x00,0x00,0x01};
|
#define __long_aligned __attribute__((aligned((sizeof(long)))))
|
||||||
|
#endif
|
||||||
|
static const u8 mac_bcast[ETH_ALEN] __long_aligned = {
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff
|
||||||
|
};
|
||||||
|
static const u8 mac_v6_allmcast[ETH_ALEN] __long_aligned = {
|
||||||
|
0x33, 0x33, 0x00, 0x00, 0x00, 0x01
|
||||||
|
};
|
||||||
static const int alb_delta_in_ticks = HZ / ALB_TIMER_TICKS_PER_SEC;
|
static const int alb_delta_in_ticks = HZ / ALB_TIMER_TICKS_PER_SEC;
|
||||||
|
|
||||||
#pragma pack(1)
|
#pragma pack(1)
|
||||||
|
@ -460,8 +467,8 @@ static void rlb_clear_slave(struct bonding *bond, struct slave *slave)
|
||||||
|
|
||||||
if (assigned_slave) {
|
if (assigned_slave) {
|
||||||
rx_hash_table[index].slave = assigned_slave;
|
rx_hash_table[index].slave = assigned_slave;
|
||||||
if (memcmp(rx_hash_table[index].mac_dst,
|
if (compare_ether_addr_64bits(rx_hash_table[index].mac_dst,
|
||||||
mac_bcast, ETH_ALEN)) {
|
mac_bcast)) {
|
||||||
bond_info->rx_hashtbl[index].ntt = 1;
|
bond_info->rx_hashtbl[index].ntt = 1;
|
||||||
bond_info->rx_ntt = 1;
|
bond_info->rx_ntt = 1;
|
||||||
/* A slave has been removed from the
|
/* A slave has been removed from the
|
||||||
|
@ -575,7 +582,7 @@ static void rlb_req_update_slave_clients(struct bonding *bond, struct slave *sla
|
||||||
client_info = &(bond_info->rx_hashtbl[hash_index]);
|
client_info = &(bond_info->rx_hashtbl[hash_index]);
|
||||||
|
|
||||||
if ((client_info->slave == slave) &&
|
if ((client_info->slave == slave) &&
|
||||||
memcmp(client_info->mac_dst, mac_bcast, ETH_ALEN)) {
|
compare_ether_addr_64bits(client_info->mac_dst, mac_bcast)) {
|
||||||
client_info->ntt = 1;
|
client_info->ntt = 1;
|
||||||
ntt = 1;
|
ntt = 1;
|
||||||
}
|
}
|
||||||
|
@ -616,9 +623,9 @@ static void rlb_req_update_subnet_clients(struct bonding *bond, __be32 src_ip)
|
||||||
* unicast mac address.
|
* unicast mac address.
|
||||||
*/
|
*/
|
||||||
if ((client_info->ip_src == src_ip) &&
|
if ((client_info->ip_src == src_ip) &&
|
||||||
memcmp(client_info->slave->dev->dev_addr,
|
compare_ether_addr_64bits(client_info->slave->dev->dev_addr,
|
||||||
bond->dev->dev_addr, ETH_ALEN) &&
|
bond->dev->dev_addr) &&
|
||||||
memcmp(client_info->mac_dst, mac_bcast, ETH_ALEN)) {
|
compare_ether_addr_64bits(client_info->mac_dst, mac_bcast)) {
|
||||||
client_info->ntt = 1;
|
client_info->ntt = 1;
|
||||||
bond_info->rx_ntt = 1;
|
bond_info->rx_ntt = 1;
|
||||||
}
|
}
|
||||||
|
@ -645,7 +652,7 @@ static struct slave *rlb_choose_channel(struct sk_buff *skb, struct bonding *bon
|
||||||
if ((client_info->ip_src == arp->ip_src) &&
|
if ((client_info->ip_src == arp->ip_src) &&
|
||||||
(client_info->ip_dst == arp->ip_dst)) {
|
(client_info->ip_dst == arp->ip_dst)) {
|
||||||
/* the entry is already assigned to this client */
|
/* the entry is already assigned to this client */
|
||||||
if (memcmp(arp->mac_dst, mac_bcast, ETH_ALEN)) {
|
if (compare_ether_addr_64bits(arp->mac_dst, mac_bcast)) {
|
||||||
/* update mac address from arp */
|
/* update mac address from arp */
|
||||||
memcpy(client_info->mac_dst, arp->mac_dst, ETH_ALEN);
|
memcpy(client_info->mac_dst, arp->mac_dst, ETH_ALEN);
|
||||||
}
|
}
|
||||||
|
@ -680,7 +687,7 @@ static struct slave *rlb_choose_channel(struct sk_buff *skb, struct bonding *bon
|
||||||
memcpy(client_info->mac_dst, arp->mac_dst, ETH_ALEN);
|
memcpy(client_info->mac_dst, arp->mac_dst, ETH_ALEN);
|
||||||
client_info->slave = assigned_slave;
|
client_info->slave = assigned_slave;
|
||||||
|
|
||||||
if (memcmp(client_info->mac_dst, mac_bcast, ETH_ALEN)) {
|
if (compare_ether_addr_64bits(client_info->mac_dst, mac_bcast)) {
|
||||||
client_info->ntt = 1;
|
client_info->ntt = 1;
|
||||||
bond->alb_info.rx_ntt = 1;
|
bond->alb_info.rx_ntt = 1;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1046,21 +1053,18 @@ static void alb_change_hw_addr_on_detach(struct bonding *bond, struct slave *sla
|
||||||
int perm_curr_diff;
|
int perm_curr_diff;
|
||||||
int perm_bond_diff;
|
int perm_bond_diff;
|
||||||
|
|
||||||
perm_curr_diff = memcmp(slave->perm_hwaddr,
|
perm_curr_diff = compare_ether_addr_64bits(slave->perm_hwaddr,
|
||||||
slave->dev->dev_addr,
|
slave->dev->dev_addr);
|
||||||
ETH_ALEN);
|
perm_bond_diff = compare_ether_addr_64bits(slave->perm_hwaddr,
|
||||||
perm_bond_diff = memcmp(slave->perm_hwaddr,
|
bond->dev->dev_addr);
|
||||||
bond->dev->dev_addr,
|
|
||||||
ETH_ALEN);
|
|
||||||
|
|
||||||
if (perm_curr_diff && perm_bond_diff) {
|
if (perm_curr_diff && perm_bond_diff) {
|
||||||
struct slave *tmp_slave;
|
struct slave *tmp_slave;
|
||||||
int i, found = 0;
|
int i, found = 0;
|
||||||
|
|
||||||
bond_for_each_slave(bond, tmp_slave, i) {
|
bond_for_each_slave(bond, tmp_slave, i) {
|
||||||
if (!memcmp(slave->perm_hwaddr,
|
if (!compare_ether_addr_64bits(slave->perm_hwaddr,
|
||||||
tmp_slave->dev->dev_addr,
|
tmp_slave->dev->dev_addr)) {
|
||||||
ETH_ALEN)) {
|
|
||||||
found = 1;
|
found = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1114,10 +1118,10 @@ static int alb_handle_addr_collision_on_attach(struct bonding *bond, struct slav
|
||||||
* check uniqueness of slave's mac address against the other
|
* check uniqueness of slave's mac address against the other
|
||||||
* slaves in the bond.
|
* slaves in the bond.
|
||||||
*/
|
*/
|
||||||
if (memcmp(slave->perm_hwaddr, bond->dev->dev_addr, ETH_ALEN)) {
|
if (compare_ether_addr_64bits(slave->perm_hwaddr, bond->dev->dev_addr)) {
|
||||||
bond_for_each_slave(bond, tmp_slave1, i) {
|
bond_for_each_slave(bond, tmp_slave1, i) {
|
||||||
if (!memcmp(tmp_slave1->dev->dev_addr, slave->dev->dev_addr,
|
if (!compare_ether_addr_64bits(tmp_slave1->dev->dev_addr,
|
||||||
ETH_ALEN)) {
|
slave->dev->dev_addr)) {
|
||||||
found = 1;
|
found = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1140,9 +1144,8 @@ static int alb_handle_addr_collision_on_attach(struct bonding *bond, struct slav
|
||||||
bond_for_each_slave(bond, tmp_slave1, i) {
|
bond_for_each_slave(bond, tmp_slave1, i) {
|
||||||
found = 0;
|
found = 0;
|
||||||
bond_for_each_slave(bond, tmp_slave2, j) {
|
bond_for_each_slave(bond, tmp_slave2, j) {
|
||||||
if (!memcmp(tmp_slave1->perm_hwaddr,
|
if (!compare_ether_addr_64bits(tmp_slave1->perm_hwaddr,
|
||||||
tmp_slave2->dev->dev_addr,
|
tmp_slave2->dev->dev_addr)) {
|
||||||
ETH_ALEN)) {
|
|
||||||
found = 1;
|
found = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1157,9 +1160,8 @@ static int alb_handle_addr_collision_on_attach(struct bonding *bond, struct slav
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!has_bond_addr) {
|
if (!has_bond_addr) {
|
||||||
if (!memcmp(tmp_slave1->dev->dev_addr,
|
if (!compare_ether_addr_64bits(tmp_slave1->dev->dev_addr,
|
||||||
bond->dev->dev_addr,
|
bond->dev->dev_addr)) {
|
||||||
ETH_ALEN)) {
|
|
||||||
|
|
||||||
has_bond_addr = tmp_slave1;
|
has_bond_addr = tmp_slave1;
|
||||||
}
|
}
|
||||||
|
@ -1313,7 +1315,7 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
|
||||||
case ETH_P_IP: {
|
case ETH_P_IP: {
|
||||||
const struct iphdr *iph = ip_hdr(skb);
|
const struct iphdr *iph = ip_hdr(skb);
|
||||||
|
|
||||||
if ((memcmp(eth_data->h_dest, mac_bcast, ETH_ALEN) == 0) ||
|
if (!compare_ether_addr_64bits(eth_data->h_dest, mac_bcast) ||
|
||||||
(iph->daddr == ip_bcast) ||
|
(iph->daddr == ip_bcast) ||
|
||||||
(iph->protocol == IPPROTO_IGMP)) {
|
(iph->protocol == IPPROTO_IGMP)) {
|
||||||
do_tx_balance = 0;
|
do_tx_balance = 0;
|
||||||
|
@ -1327,7 +1329,7 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
|
||||||
/* IPv6 doesn't really use broadcast mac address, but leave
|
/* IPv6 doesn't really use broadcast mac address, but leave
|
||||||
* that here just in case.
|
* that here just in case.
|
||||||
*/
|
*/
|
||||||
if (memcmp(eth_data->h_dest, mac_bcast, ETH_ALEN) == 0) {
|
if (!compare_ether_addr_64bits(eth_data->h_dest, mac_bcast)) {
|
||||||
do_tx_balance = 0;
|
do_tx_balance = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1335,7 +1337,7 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
|
||||||
/* IPv6 uses all-nodes multicast as an equivalent to
|
/* IPv6 uses all-nodes multicast as an equivalent to
|
||||||
* broadcasts in IPv4.
|
* broadcasts in IPv4.
|
||||||
*/
|
*/
|
||||||
if (memcmp(eth_data->h_dest, mac_v6_allmcast, ETH_ALEN) == 0) {
|
if (!compare_ether_addr_64bits(eth_data->h_dest, mac_v6_allmcast)) {
|
||||||
do_tx_balance = 0;
|
do_tx_balance = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1660,8 +1662,8 @@ void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave
|
||||||
struct slave *tmp_slave;
|
struct slave *tmp_slave;
|
||||||
/* find slave that is holding the bond's mac address */
|
/* find slave that is holding the bond's mac address */
|
||||||
bond_for_each_slave(bond, tmp_slave, i) {
|
bond_for_each_slave(bond, tmp_slave, i) {
|
||||||
if (!memcmp(tmp_slave->dev->dev_addr,
|
if (!compare_ether_addr_64bits(tmp_slave->dev->dev_addr,
|
||||||
bond->dev->dev_addr, ETH_ALEN)) {
|
bond->dev->dev_addr)) {
|
||||||
swap_slave = tmp_slave;
|
swap_slave = tmp_slave;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1739,7 +1741,8 @@ int bond_alb_set_mac_address(struct net_device *bond_dev, void *addr)
|
||||||
swap_slave = NULL;
|
swap_slave = NULL;
|
||||||
|
|
||||||
bond_for_each_slave(bond, slave, i) {
|
bond_for_each_slave(bond, slave, i) {
|
||||||
if (!memcmp(slave->dev->dev_addr, bond_dev->dev_addr, ETH_ALEN)) {
|
if (!compare_ether_addr_64bits(slave->dev->dev_addr,
|
||||||
|
bond_dev->dev_addr)) {
|
||||||
swap_slave = slave;
|
swap_slave = slave;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -163,9 +163,9 @@ struct slave {
|
||||||
u32 original_flags;
|
u32 original_flags;
|
||||||
u32 original_mtu;
|
u32 original_mtu;
|
||||||
u32 link_failure_count;
|
u32 link_failure_count;
|
||||||
|
u8 perm_hwaddr[ETH_ALEN];
|
||||||
u16 speed;
|
u16 speed;
|
||||||
u8 duplex;
|
u8 duplex;
|
||||||
u8 perm_hwaddr[ETH_ALEN];
|
|
||||||
struct ad_slave_info ad_info; /* HUGE - better to dynamically alloc */
|
struct ad_slave_info ad_info; /* HUGE - better to dynamically alloc */
|
||||||
struct tlb_slave_info tlb_info;
|
struct tlb_slave_info tlb_info;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue