diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
commit | c71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch) | |
tree | ecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/net/bonding/bond_alb.c | |
parent | ea53c912f8a86a8567697115b6a0d8152beee5c8 (diff) | |
parent | 6a00f206debf8a5c8899055726ad127dbeeed098 (diff) |
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts:
litmus/sched_cedf.c
Diffstat (limited to 'drivers/net/bonding/bond_alb.c')
-rw-r--r-- | drivers/net/bonding/bond_alb.c | 101 |
1 files changed, 17 insertions, 84 deletions
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index 26bb118c4533..2df9276720a0 100644 --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c | |||
@@ -44,42 +44,6 @@ | |||
44 | #include "bond_alb.h" | 44 | #include "bond_alb.h" |
45 | 45 | ||
46 | 46 | ||
47 | #define ALB_TIMER_TICKS_PER_SEC 10 /* should be a divisor of HZ */ | ||
48 | #define BOND_TLB_REBALANCE_INTERVAL 10 /* In seconds, periodic re-balancing. | ||
49 | * Used for division - never set | ||
50 | * to zero !!! | ||
51 | */ | ||
52 | #define BOND_ALB_LP_INTERVAL 1 /* In seconds, periodic send of | ||
53 | * learning packets to the switch | ||
54 | */ | ||
55 | |||
56 | #define BOND_TLB_REBALANCE_TICKS (BOND_TLB_REBALANCE_INTERVAL \ | ||
57 | * ALB_TIMER_TICKS_PER_SEC) | ||
58 | |||
59 | #define BOND_ALB_LP_TICKS (BOND_ALB_LP_INTERVAL \ | ||
60 | * ALB_TIMER_TICKS_PER_SEC) | ||
61 | |||
62 | #define TLB_HASH_TABLE_SIZE 256 /* The size of the clients hash table. | ||
63 | * Note that this value MUST NOT be smaller | ||
64 | * because the key hash table is BYTE wide ! | ||
65 | */ | ||
66 | |||
67 | |||
68 | #define TLB_NULL_INDEX 0xffffffff | ||
69 | #define MAX_LP_BURST 3 | ||
70 | |||
71 | /* rlb defs */ | ||
72 | #define RLB_HASH_TABLE_SIZE 256 | ||
73 | #define RLB_NULL_INDEX 0xffffffff | ||
74 | #define RLB_UPDATE_DELAY 2*ALB_TIMER_TICKS_PER_SEC /* 2 seconds */ | ||
75 | #define RLB_ARP_BURST_SIZE 2 | ||
76 | #define RLB_UPDATE_RETRY 3 /* 3-ticks - must be smaller than the rlb | ||
77 | * rebalance interval (5 min). | ||
78 | */ | ||
79 | /* RLB_PROMISC_TIMEOUT = 10 sec equals the time that the current slave is | ||
80 | * promiscuous after failover | ||
81 | */ | ||
82 | #define RLB_PROMISC_TIMEOUT 10*ALB_TIMER_TICKS_PER_SEC | ||
83 | 47 | ||
84 | #ifndef __long_aligned | 48 | #ifndef __long_aligned |
85 | #define __long_aligned __attribute__((aligned((sizeof(long))))) | 49 | #define __long_aligned __attribute__((aligned((sizeof(long))))) |
@@ -199,8 +163,6 @@ static int tlb_initialize(struct bonding *bond) | |||
199 | struct tlb_client_info *new_hashtbl; | 163 | struct tlb_client_info *new_hashtbl; |
200 | int i; | 164 | int i; |
201 | 165 | ||
202 | spin_lock_init(&(bond_info->tx_hashtbl_lock)); | ||
203 | |||
204 | new_hashtbl = kzalloc(size, GFP_KERNEL); | 166 | new_hashtbl = kzalloc(size, GFP_KERNEL); |
205 | if (!new_hashtbl) { | 167 | if (!new_hashtbl) { |
206 | pr_err("%s: Error: Failed to allocate TLB hash table\n", | 168 | pr_err("%s: Error: Failed to allocate TLB hash table\n", |
@@ -212,7 +174,7 @@ static int tlb_initialize(struct bonding *bond) | |||
212 | bond_info->tx_hashtbl = new_hashtbl; | 174 | bond_info->tx_hashtbl = new_hashtbl; |
213 | 175 | ||
214 | for (i = 0; i < TLB_HASH_TABLE_SIZE; i++) { | 176 | for (i = 0; i < TLB_HASH_TABLE_SIZE; i++) { |
215 | tlb_init_table_entry(&bond_info->tx_hashtbl[i], 1); | 177 | tlb_init_table_entry(&bond_info->tx_hashtbl[i], 0); |
216 | } | 178 | } |
217 | 179 | ||
218 | _unlock_tx_hashtbl(bond); | 180 | _unlock_tx_hashtbl(bond); |
@@ -344,45 +306,33 @@ static void rlb_update_entry_from_arp(struct bonding *bond, struct arp_pkt *arp) | |||
344 | _unlock_rx_hashtbl(bond); | 306 | _unlock_rx_hashtbl(bond); |
345 | } | 307 | } |
346 | 308 | ||
347 | static int rlb_arp_recv(struct sk_buff *skb, struct net_device *bond_dev, struct packet_type *ptype, struct net_device *orig_dev) | 309 | static void rlb_arp_recv(struct sk_buff *skb, struct bonding *bond, |
310 | struct slave *slave) | ||
348 | { | 311 | { |
349 | struct bonding *bond; | 312 | struct arp_pkt *arp; |
350 | struct arp_pkt *arp = (struct arp_pkt *)skb->data; | ||
351 | int res = NET_RX_DROP; | ||
352 | |||
353 | while (bond_dev->priv_flags & IFF_802_1Q_VLAN) | ||
354 | bond_dev = vlan_dev_real_dev(bond_dev); | ||
355 | 313 | ||
356 | if (!(bond_dev->priv_flags & IFF_BONDING) || | 314 | if (skb->protocol != cpu_to_be16(ETH_P_ARP)) |
357 | !(bond_dev->flags & IFF_MASTER)) | 315 | return; |
358 | goto out; | ||
359 | 316 | ||
317 | arp = (struct arp_pkt *) skb->data; | ||
360 | if (!arp) { | 318 | if (!arp) { |
361 | pr_debug("Packet has no ARP data\n"); | 319 | pr_debug("Packet has no ARP data\n"); |
362 | goto out; | 320 | return; |
363 | } | 321 | } |
364 | 322 | ||
365 | if (!pskb_may_pull(skb, arp_hdr_len(bond_dev))) | 323 | if (!pskb_may_pull(skb, arp_hdr_len(bond->dev))) |
366 | goto out; | 324 | return; |
367 | 325 | ||
368 | if (skb->len < sizeof(struct arp_pkt)) { | 326 | if (skb->len < sizeof(struct arp_pkt)) { |
369 | pr_debug("Packet is too small to be an ARP\n"); | 327 | pr_debug("Packet is too small to be an ARP\n"); |
370 | goto out; | 328 | return; |
371 | } | 329 | } |
372 | 330 | ||
373 | if (arp->op_code == htons(ARPOP_REPLY)) { | 331 | if (arp->op_code == htons(ARPOP_REPLY)) { |
374 | /* update rx hash table for this ARP */ | 332 | /* update rx hash table for this ARP */ |
375 | bond = netdev_priv(bond_dev); | ||
376 | rlb_update_entry_from_arp(bond, arp); | 333 | rlb_update_entry_from_arp(bond, arp); |
377 | pr_debug("Server received an ARP Reply from client\n"); | 334 | pr_debug("Server received an ARP Reply from client\n"); |
378 | } | 335 | } |
379 | |||
380 | res = NET_RX_SUCCESS; | ||
381 | |||
382 | out: | ||
383 | dev_kfree_skb(skb); | ||
384 | |||
385 | return res; | ||
386 | } | 336 | } |
387 | 337 | ||
388 | /* Caller must hold bond lock for read */ | 338 | /* Caller must hold bond lock for read */ |
@@ -636,7 +586,7 @@ static struct slave *rlb_choose_channel(struct sk_buff *skb, struct bonding *bon | |||
636 | 586 | ||
637 | _lock_rx_hashtbl(bond); | 587 | _lock_rx_hashtbl(bond); |
638 | 588 | ||
639 | hash_index = _simple_hash((u8 *)&arp->ip_dst, sizeof(arp->ip_src)); | 589 | hash_index = _simple_hash((u8 *)&arp->ip_dst, sizeof(arp->ip_dst)); |
640 | client_info = &(bond_info->rx_hashtbl[hash_index]); | 590 | client_info = &(bond_info->rx_hashtbl[hash_index]); |
641 | 591 | ||
642 | if (client_info->assigned) { | 592 | if (client_info->assigned) { |
@@ -733,7 +683,7 @@ static struct slave *rlb_arp_xmit(struct sk_buff *skb, struct bonding *bond) | |||
733 | */ | 683 | */ |
734 | rlb_choose_channel(skb, bond); | 684 | rlb_choose_channel(skb, bond); |
735 | 685 | ||
736 | /* The ARP relpy packets must be delayed so that | 686 | /* The ARP reply packets must be delayed so that |
737 | * they can cancel out the influence of the ARP request. | 687 | * they can cancel out the influence of the ARP request. |
738 | */ | 688 | */ |
739 | bond->alb_info.rlb_update_delay_counter = RLB_UPDATE_DELAY; | 689 | bond->alb_info.rlb_update_delay_counter = RLB_UPDATE_DELAY; |
@@ -791,13 +741,10 @@ static void rlb_init_table_entry(struct rlb_client_info *entry) | |||
791 | static int rlb_initialize(struct bonding *bond) | 741 | static int rlb_initialize(struct bonding *bond) |
792 | { | 742 | { |
793 | struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond)); | 743 | struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond)); |
794 | struct packet_type *pk_type = &(BOND_ALB_INFO(bond).rlb_pkt_type); | ||
795 | struct rlb_client_info *new_hashtbl; | 744 | struct rlb_client_info *new_hashtbl; |
796 | int size = RLB_HASH_TABLE_SIZE * sizeof(struct rlb_client_info); | 745 | int size = RLB_HASH_TABLE_SIZE * sizeof(struct rlb_client_info); |
797 | int i; | 746 | int i; |
798 | 747 | ||
799 | spin_lock_init(&(bond_info->rx_hashtbl_lock)); | ||
800 | |||
801 | new_hashtbl = kmalloc(size, GFP_KERNEL); | 748 | new_hashtbl = kmalloc(size, GFP_KERNEL); |
802 | if (!new_hashtbl) { | 749 | if (!new_hashtbl) { |
803 | pr_err("%s: Error: Failed to allocate RLB hash table\n", | 750 | pr_err("%s: Error: Failed to allocate RLB hash table\n", |
@@ -816,13 +763,8 @@ static int rlb_initialize(struct bonding *bond) | |||
816 | 763 | ||
817 | _unlock_rx_hashtbl(bond); | 764 | _unlock_rx_hashtbl(bond); |
818 | 765 | ||
819 | /*initialize packet type*/ | ||
820 | pk_type->type = cpu_to_be16(ETH_P_ARP); | ||
821 | pk_type->dev = bond->dev; | ||
822 | pk_type->func = rlb_arp_recv; | ||
823 | |||
824 | /* register to receive ARPs */ | 766 | /* register to receive ARPs */ |
825 | dev_add_pack(pk_type); | 767 | bond->recv_probe = rlb_arp_recv; |
826 | 768 | ||
827 | return 0; | 769 | return 0; |
828 | } | 770 | } |
@@ -831,8 +773,6 @@ static void rlb_deinitialize(struct bonding *bond) | |||
831 | { | 773 | { |
832 | struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond)); | 774 | struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond)); |
833 | 775 | ||
834 | dev_remove_pack(&(bond_info->rlb_pkt_type)); | ||
835 | |||
836 | _lock_rx_hashtbl(bond); | 776 | _lock_rx_hashtbl(bond); |
837 | 777 | ||
838 | kfree(bond_info->rx_hashtbl); | 778 | kfree(bond_info->rx_hashtbl); |
@@ -1074,7 +1014,7 @@ static void alb_change_hw_addr_on_detach(struct bonding *bond, struct slave *sla | |||
1074 | * | 1014 | * |
1075 | * If the permanent hw address of @slave is @bond's hw address, we need to | 1015 | * If the permanent hw address of @slave is @bond's hw address, we need to |
1076 | * find a different hw address to give @slave, that isn't in use by any other | 1016 | * find a different hw address to give @slave, that isn't in use by any other |
1077 | * slave in the bond. This address must be, of course, one of the premanent | 1017 | * slave in the bond. This address must be, of course, one of the permanent |
1078 | * addresses of the other slaves. | 1018 | * addresses of the other slaves. |
1079 | * | 1019 | * |
1080 | * We go over the slave list, and for each slave there we compare its | 1020 | * We go over the slave list, and for each slave there we compare its |
@@ -1281,16 +1221,10 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev) | |||
1281 | skb_reset_mac_header(skb); | 1221 | skb_reset_mac_header(skb); |
1282 | eth_data = eth_hdr(skb); | 1222 | eth_data = eth_hdr(skb); |
1283 | 1223 | ||
1284 | /* make sure that the curr_active_slave and the slaves list do | 1224 | /* make sure that the curr_active_slave do not change during tx |
1285 | * not change during tx | ||
1286 | */ | 1225 | */ |
1287 | read_lock(&bond->lock); | ||
1288 | read_lock(&bond->curr_slave_lock); | 1226 | read_lock(&bond->curr_slave_lock); |
1289 | 1227 | ||
1290 | if (!BOND_IS_OK(bond)) { | ||
1291 | goto out; | ||
1292 | } | ||
1293 | |||
1294 | switch (ntohs(skb->protocol)) { | 1228 | switch (ntohs(skb->protocol)) { |
1295 | case ETH_P_IP: { | 1229 | case ETH_P_IP: { |
1296 | const struct iphdr *iph = ip_hdr(skb); | 1230 | const struct iphdr *iph = ip_hdr(skb); |
@@ -1390,13 +1324,12 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev) | |||
1390 | } | 1324 | } |
1391 | } | 1325 | } |
1392 | 1326 | ||
1393 | out: | ||
1394 | if (res) { | 1327 | if (res) { |
1395 | /* no suitable interface, frame not sent */ | 1328 | /* no suitable interface, frame not sent */ |
1396 | dev_kfree_skb(skb); | 1329 | dev_kfree_skb(skb); |
1397 | } | 1330 | } |
1398 | read_unlock(&bond->curr_slave_lock); | 1331 | read_unlock(&bond->curr_slave_lock); |
1399 | read_unlock(&bond->lock); | 1332 | |
1400 | return NETDEV_TX_OK; | 1333 | return NETDEV_TX_OK; |
1401 | } | 1334 | } |
1402 | 1335 | ||