mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	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
					
				
					 2 changed files with 38 additions and 35 deletions
				
			
		| 
						 | 
					@ -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 a new issue