aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bonding/bond_alb.c
diff options
context:
space:
mode:
authorMaxim Uvarov <maxim.uvarov@oracle.com>2012-01-09 07:01:37 -0500
committerDavid S. Miller <davem@davemloft.net>2012-01-11 15:52:26 -0500
commitf515e6b77045b4b1f54617d9fbf4a22b95a58757 (patch)
treed01dfbd06052f13c88aa6a93b69e9d33cc87c20c /drivers/net/bonding/bond_alb.c
parentd6c25beba35a76c002bff9235484d75a6f8e7e6b (diff)
bond_alb: don't disable softirq under bond_alb_xmit
No need to lock soft irqs under bond_alb_xmit() which already has softirq disabled. Changes: 1. add non-bh/bh version to tlb_clear_slave() 2. represent BH and non BH hash table locks _lock_rx_hashtbl_bh/_unlock_rx_hashtbl_bh _lock_rx_hashtbl/_unlock_rx_hashtbl _lock_tx_hashtbl_bh/_unlock_tx_hashtbl_bh _lock_tx_hashtbl/_unlock_tx_hashtbl Signed-off-by: Maxim Uvarov <maxim.uvarov@oracle.com> Signed-off-by: Cong Wang <amwang@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bonding/bond_alb.c')
-rw-r--r--drivers/net/bonding/bond_alb.c112
1 files changed, 76 insertions, 36 deletions
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index 106b88a04738..342626f4bc46 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -99,16 +99,26 @@ static inline u8 _simple_hash(const u8 *hash_start, int hash_size)
99 99
100/*********************** tlb specific functions ***************************/ 100/*********************** tlb specific functions ***************************/
101 101
102static inline void _lock_tx_hashtbl(struct bonding *bond) 102static inline void _lock_tx_hashtbl_bh(struct bonding *bond)
103{ 103{
104 spin_lock_bh(&(BOND_ALB_INFO(bond).tx_hashtbl_lock)); 104 spin_lock_bh(&(BOND_ALB_INFO(bond).tx_hashtbl_lock));
105} 105}
106 106
107static inline void _unlock_tx_hashtbl(struct bonding *bond) 107static inline void _unlock_tx_hashtbl_bh(struct bonding *bond)
108{ 108{
109 spin_unlock_bh(&(BOND_ALB_INFO(bond).tx_hashtbl_lock)); 109 spin_unlock_bh(&(BOND_ALB_INFO(bond).tx_hashtbl_lock));
110} 110}
111 111
112static inline void _lock_tx_hashtbl(struct bonding *bond)
113{
114 spin_lock(&(BOND_ALB_INFO(bond).tx_hashtbl_lock));
115}
116
117static inline void _unlock_tx_hashtbl(struct bonding *bond)
118{
119 spin_unlock(&(BOND_ALB_INFO(bond).tx_hashtbl_lock));
120}
121
112/* Caller must hold tx_hashtbl lock */ 122/* Caller must hold tx_hashtbl lock */
113static inline void tlb_init_table_entry(struct tlb_client_info *entry, int save_load) 123static inline void tlb_init_table_entry(struct tlb_client_info *entry, int save_load)
114{ 124{
@@ -129,14 +139,13 @@ static inline void tlb_init_slave(struct slave *slave)
129 SLAVE_TLB_INFO(slave).head = TLB_NULL_INDEX; 139 SLAVE_TLB_INFO(slave).head = TLB_NULL_INDEX;
130} 140}
131 141
132/* Caller must hold bond lock for read */ 142/* Caller must hold bond lock for read, BH disabled */
133static void tlb_clear_slave(struct bonding *bond, struct slave *slave, int save_load) 143static void __tlb_clear_slave(struct bonding *bond, struct slave *slave,
144 int save_load)
134{ 145{
135 struct tlb_client_info *tx_hash_table; 146 struct tlb_client_info *tx_hash_table;
136 u32 index; 147 u32 index;
137 148
138 _lock_tx_hashtbl(bond);
139
140 /* clear slave from tx_hashtbl */ 149 /* clear slave from tx_hashtbl */
141 tx_hash_table = BOND_ALB_INFO(bond).tx_hashtbl; 150 tx_hash_table = BOND_ALB_INFO(bond).tx_hashtbl;
142 151
@@ -151,8 +160,15 @@ static void tlb_clear_slave(struct bonding *bond, struct slave *slave, int save_
151 } 160 }
152 161
153 tlb_init_slave(slave); 162 tlb_init_slave(slave);
163}
154 164
155 _unlock_tx_hashtbl(bond); 165/* Caller must hold bond lock for read */
166static void tlb_clear_slave(struct bonding *bond, struct slave *slave,
167 int save_load)
168{
169 _lock_tx_hashtbl_bh(bond);
170 __tlb_clear_slave(bond, slave, save_load);
171 _unlock_tx_hashtbl_bh(bond);
156} 172}
157 173
158/* Must be called before starting the monitor timer */ 174/* Must be called before starting the monitor timer */
@@ -169,7 +185,7 @@ static int tlb_initialize(struct bonding *bond)
169 bond->dev->name); 185 bond->dev->name);
170 return -1; 186 return -1;
171 } 187 }
172 _lock_tx_hashtbl(bond); 188 _lock_tx_hashtbl_bh(bond);
173 189
174 bond_info->tx_hashtbl = new_hashtbl; 190 bond_info->tx_hashtbl = new_hashtbl;
175 191
@@ -177,7 +193,7 @@ static int tlb_initialize(struct bonding *bond)
177 tlb_init_table_entry(&bond_info->tx_hashtbl[i], 0); 193 tlb_init_table_entry(&bond_info->tx_hashtbl[i], 0);
178 } 194 }
179 195
180 _unlock_tx_hashtbl(bond); 196 _unlock_tx_hashtbl_bh(bond);
181 197
182 return 0; 198 return 0;
183} 199}
@@ -187,12 +203,12 @@ static void tlb_deinitialize(struct bonding *bond)
187{ 203{
188 struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond)); 204 struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
189 205
190 _lock_tx_hashtbl(bond); 206 _lock_tx_hashtbl_bh(bond);
191 207
192 kfree(bond_info->tx_hashtbl); 208 kfree(bond_info->tx_hashtbl);
193 bond_info->tx_hashtbl = NULL; 209 bond_info->tx_hashtbl = NULL;
194 210
195 _unlock_tx_hashtbl(bond); 211 _unlock_tx_hashtbl_bh(bond);
196} 212}
197 213
198static long long compute_gap(struct slave *slave) 214static long long compute_gap(struct slave *slave)
@@ -226,15 +242,13 @@ static struct slave *tlb_get_least_loaded_slave(struct bonding *bond)
226 return least_loaded; 242 return least_loaded;
227} 243}
228 244
229/* Caller must hold bond lock for read */ 245static struct slave *__tlb_choose_channel(struct bonding *bond, u32 hash_index,
230static struct slave *tlb_choose_channel(struct bonding *bond, u32 hash_index, u32 skb_len) 246 u32 skb_len)
231{ 247{
232 struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond)); 248 struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
233 struct tlb_client_info *hash_table; 249 struct tlb_client_info *hash_table;
234 struct slave *assigned_slave; 250 struct slave *assigned_slave;
235 251
236 _lock_tx_hashtbl(bond);
237
238 hash_table = bond_info->tx_hashtbl; 252 hash_table = bond_info->tx_hashtbl;
239 assigned_slave = hash_table[hash_index].tx_slave; 253 assigned_slave = hash_table[hash_index].tx_slave;
240 if (!assigned_slave) { 254 if (!assigned_slave) {
@@ -263,22 +277,46 @@ static struct slave *tlb_choose_channel(struct bonding *bond, u32 hash_index, u3
263 hash_table[hash_index].tx_bytes += skb_len; 277 hash_table[hash_index].tx_bytes += skb_len;
264 } 278 }
265 279
266 _unlock_tx_hashtbl(bond);
267
268 return assigned_slave; 280 return assigned_slave;
269} 281}
270 282
283/* Caller must hold bond lock for read */
284static struct slave *tlb_choose_channel(struct bonding *bond, u32 hash_index,
285 u32 skb_len)
286{
287 struct slave *tx_slave;
288 /*
289 * We don't need to disable softirq here, becase
290 * tlb_choose_channel() is only called by bond_alb_xmit()
291 * which already has softirq disabled.
292 */
293 _lock_tx_hashtbl(bond);
294 tx_slave = __tlb_choose_channel(bond, hash_index, skb_len);
295 _unlock_tx_hashtbl(bond);
296 return tx_slave;
297}
298
271/*********************** rlb specific functions ***************************/ 299/*********************** rlb specific functions ***************************/
272static inline void _lock_rx_hashtbl(struct bonding *bond) 300static inline void _lock_rx_hashtbl_bh(struct bonding *bond)
273{ 301{
274 spin_lock_bh(&(BOND_ALB_INFO(bond).rx_hashtbl_lock)); 302 spin_lock_bh(&(BOND_ALB_INFO(bond).rx_hashtbl_lock));
275} 303}
276 304
277static inline void _unlock_rx_hashtbl(struct bonding *bond) 305static inline void _unlock_rx_hashtbl_bh(struct bonding *bond)
278{ 306{
279 spin_unlock_bh(&(BOND_ALB_INFO(bond).rx_hashtbl_lock)); 307 spin_unlock_bh(&(BOND_ALB_INFO(bond).rx_hashtbl_lock));
280} 308}
281 309
310static inline void _lock_rx_hashtbl(struct bonding *bond)
311{
312 spin_lock(&(BOND_ALB_INFO(bond).rx_hashtbl_lock));
313}
314
315static inline void _unlock_rx_hashtbl(struct bonding *bond)
316{
317 spin_unlock(&(BOND_ALB_INFO(bond).rx_hashtbl_lock));
318}
319
282/* when an ARP REPLY is received from a client update its info 320/* when an ARP REPLY is received from a client update its info
283 * in the rx_hashtbl 321 * in the rx_hashtbl
284 */ 322 */
@@ -288,7 +326,7 @@ static void rlb_update_entry_from_arp(struct bonding *bond, struct arp_pkt *arp)
288 struct rlb_client_info *client_info; 326 struct rlb_client_info *client_info;
289 u32 hash_index; 327 u32 hash_index;
290 328
291 _lock_rx_hashtbl(bond); 329 _lock_rx_hashtbl_bh(bond);
292 330
293 hash_index = _simple_hash((u8*)&(arp->ip_src), sizeof(arp->ip_src)); 331 hash_index = _simple_hash((u8*)&(arp->ip_src), sizeof(arp->ip_src));
294 client_info = &(bond_info->rx_hashtbl[hash_index]); 332 client_info = &(bond_info->rx_hashtbl[hash_index]);
@@ -303,7 +341,7 @@ static void rlb_update_entry_from_arp(struct bonding *bond, struct arp_pkt *arp)
303 bond_info->rx_ntt = 1; 341 bond_info->rx_ntt = 1;
304 } 342 }
305 343
306 _unlock_rx_hashtbl(bond); 344 _unlock_rx_hashtbl_bh(bond);
307} 345}
308 346
309static void rlb_arp_recv(struct sk_buff *skb, struct bonding *bond, 347static void rlb_arp_recv(struct sk_buff *skb, struct bonding *bond,
@@ -401,7 +439,7 @@ static void rlb_clear_slave(struct bonding *bond, struct slave *slave)
401 u32 index, next_index; 439 u32 index, next_index;
402 440
403 /* clear slave from rx_hashtbl */ 441 /* clear slave from rx_hashtbl */
404 _lock_rx_hashtbl(bond); 442 _lock_rx_hashtbl_bh(bond);
405 443
406 rx_hash_table = bond_info->rx_hashtbl; 444 rx_hash_table = bond_info->rx_hashtbl;
407 index = bond_info->rx_hashtbl_head; 445 index = bond_info->rx_hashtbl_head;
@@ -432,7 +470,7 @@ static void rlb_clear_slave(struct bonding *bond, struct slave *slave)
432 } 470 }
433 } 471 }
434 472
435 _unlock_rx_hashtbl(bond); 473 _unlock_rx_hashtbl_bh(bond);
436 474
437 write_lock_bh(&bond->curr_slave_lock); 475 write_lock_bh(&bond->curr_slave_lock);
438 476
@@ -489,7 +527,7 @@ static void rlb_update_rx_clients(struct bonding *bond)
489 struct rlb_client_info *client_info; 527 struct rlb_client_info *client_info;
490 u32 hash_index; 528 u32 hash_index;
491 529
492 _lock_rx_hashtbl(bond); 530 _lock_rx_hashtbl_bh(bond);
493 531
494 hash_index = bond_info->rx_hashtbl_head; 532 hash_index = bond_info->rx_hashtbl_head;
495 for (; hash_index != RLB_NULL_INDEX; hash_index = client_info->next) { 533 for (; hash_index != RLB_NULL_INDEX; hash_index = client_info->next) {
@@ -507,7 +545,7 @@ static void rlb_update_rx_clients(struct bonding *bond)
507 */ 545 */
508 bond_info->rlb_update_delay_counter = RLB_UPDATE_DELAY; 546 bond_info->rlb_update_delay_counter = RLB_UPDATE_DELAY;
509 547
510 _unlock_rx_hashtbl(bond); 548 _unlock_rx_hashtbl_bh(bond);
511} 549}
512 550
513/* The slave was assigned a new mac address - update the clients */ 551/* The slave was assigned a new mac address - update the clients */
@@ -518,7 +556,7 @@ static void rlb_req_update_slave_clients(struct bonding *bond, struct slave *sla
518 int ntt = 0; 556 int ntt = 0;
519 u32 hash_index; 557 u32 hash_index;
520 558
521 _lock_rx_hashtbl(bond); 559 _lock_rx_hashtbl_bh(bond);
522 560
523 hash_index = bond_info->rx_hashtbl_head; 561 hash_index = bond_info->rx_hashtbl_head;
524 for (; hash_index != RLB_NULL_INDEX; hash_index = client_info->next) { 562 for (; hash_index != RLB_NULL_INDEX; hash_index = client_info->next) {
@@ -538,7 +576,7 @@ static void rlb_req_update_slave_clients(struct bonding *bond, struct slave *sla
538 bond_info->rlb_update_retry_counter = RLB_UPDATE_RETRY; 576 bond_info->rlb_update_retry_counter = RLB_UPDATE_RETRY;
539 } 577 }
540 578
541 _unlock_rx_hashtbl(bond); 579 _unlock_rx_hashtbl_bh(bond);
542} 580}
543 581
544/* mark all clients using src_ip to be updated */ 582/* mark all clients using src_ip to be updated */
@@ -709,7 +747,7 @@ static void rlb_rebalance(struct bonding *bond)
709 int ntt; 747 int ntt;
710 u32 hash_index; 748 u32 hash_index;
711 749
712 _lock_rx_hashtbl(bond); 750 _lock_rx_hashtbl_bh(bond);
713 751
714 ntt = 0; 752 ntt = 0;
715 hash_index = bond_info->rx_hashtbl_head; 753 hash_index = bond_info->rx_hashtbl_head;
@@ -727,7 +765,7 @@ static void rlb_rebalance(struct bonding *bond)
727 if (ntt) { 765 if (ntt) {
728 bond_info->rx_ntt = 1; 766 bond_info->rx_ntt = 1;
729 } 767 }
730 _unlock_rx_hashtbl(bond); 768 _unlock_rx_hashtbl_bh(bond);
731} 769}
732 770
733/* Caller must hold rx_hashtbl lock */ 771/* Caller must hold rx_hashtbl lock */
@@ -751,7 +789,7 @@ static int rlb_initialize(struct bonding *bond)
751 bond->dev->name); 789 bond->dev->name);
752 return -1; 790 return -1;
753 } 791 }
754 _lock_rx_hashtbl(bond); 792 _lock_rx_hashtbl_bh(bond);
755 793
756 bond_info->rx_hashtbl = new_hashtbl; 794 bond_info->rx_hashtbl = new_hashtbl;
757 795
@@ -761,7 +799,7 @@ static int rlb_initialize(struct bonding *bond)
761 rlb_init_table_entry(bond_info->rx_hashtbl + i); 799 rlb_init_table_entry(bond_info->rx_hashtbl + i);
762 } 800 }
763 801
764 _unlock_rx_hashtbl(bond); 802 _unlock_rx_hashtbl_bh(bond);
765 803
766 /* register to receive ARPs */ 804 /* register to receive ARPs */
767 bond->recv_probe = rlb_arp_recv; 805 bond->recv_probe = rlb_arp_recv;
@@ -773,13 +811,13 @@ static void rlb_deinitialize(struct bonding *bond)
773{ 811{
774 struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond)); 812 struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
775 813
776 _lock_rx_hashtbl(bond); 814 _lock_rx_hashtbl_bh(bond);
777 815
778 kfree(bond_info->rx_hashtbl); 816 kfree(bond_info->rx_hashtbl);
779 bond_info->rx_hashtbl = NULL; 817 bond_info->rx_hashtbl = NULL;
780 bond_info->rx_hashtbl_head = RLB_NULL_INDEX; 818 bond_info->rx_hashtbl_head = RLB_NULL_INDEX;
781 819
782 _unlock_rx_hashtbl(bond); 820 _unlock_rx_hashtbl_bh(bond);
783} 821}
784 822
785static void rlb_clear_vlan(struct bonding *bond, unsigned short vlan_id) 823static void rlb_clear_vlan(struct bonding *bond, unsigned short vlan_id)
@@ -787,7 +825,7 @@ static void rlb_clear_vlan(struct bonding *bond, unsigned short vlan_id)
787 struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond)); 825 struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
788 u32 curr_index; 826 u32 curr_index;
789 827
790 _lock_rx_hashtbl(bond); 828 _lock_rx_hashtbl_bh(bond);
791 829
792 curr_index = bond_info->rx_hashtbl_head; 830 curr_index = bond_info->rx_hashtbl_head;
793 while (curr_index != RLB_NULL_INDEX) { 831 while (curr_index != RLB_NULL_INDEX) {
@@ -812,7 +850,7 @@ static void rlb_clear_vlan(struct bonding *bond, unsigned short vlan_id)
812 curr_index = next_index; 850 curr_index = next_index;
813 } 851 }
814 852
815 _unlock_rx_hashtbl(bond); 853 _unlock_rx_hashtbl_bh(bond);
816} 854}
817 855
818/*********************** tlb/rlb shared functions *********************/ 856/*********************** tlb/rlb shared functions *********************/
@@ -1320,7 +1358,9 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
1320 res = bond_dev_queue_xmit(bond, skb, tx_slave->dev); 1358 res = bond_dev_queue_xmit(bond, skb, tx_slave->dev);
1321 } else { 1359 } else {
1322 if (tx_slave) { 1360 if (tx_slave) {
1323 tlb_clear_slave(bond, tx_slave, 0); 1361 _lock_tx_hashtbl(bond);
1362 __tlb_clear_slave(bond, tx_slave, 0);
1363 _unlock_tx_hashtbl(bond);
1324 } 1364 }
1325 } 1365 }
1326 1366