aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/bcast.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc/bcast.c')
-rw-r--r--net/tipc/bcast.c58
1 files changed, 36 insertions, 22 deletions
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
index a7b04f397c12..2c4ecbe50082 100644
--- a/net/tipc/bcast.c
+++ b/net/tipc/bcast.c
@@ -107,22 +107,22 @@ static spinlock_t bc_lock = SPIN_LOCK_UNLOCKED;
107char tipc_bclink_name[] = "multicast-link"; 107char tipc_bclink_name[] = "multicast-link";
108 108
109 109
110static inline u32 buf_seqno(struct sk_buff *buf) 110static u32 buf_seqno(struct sk_buff *buf)
111{ 111{
112 return msg_seqno(buf_msg(buf)); 112 return msg_seqno(buf_msg(buf));
113} 113}
114 114
115static inline u32 bcbuf_acks(struct sk_buff *buf) 115static u32 bcbuf_acks(struct sk_buff *buf)
116{ 116{
117 return (u32)(unsigned long)TIPC_SKB_CB(buf)->handle; 117 return (u32)(unsigned long)TIPC_SKB_CB(buf)->handle;
118} 118}
119 119
120static inline void bcbuf_set_acks(struct sk_buff *buf, u32 acks) 120static void bcbuf_set_acks(struct sk_buff *buf, u32 acks)
121{ 121{
122 TIPC_SKB_CB(buf)->handle = (void *)(unsigned long)acks; 122 TIPC_SKB_CB(buf)->handle = (void *)(unsigned long)acks;
123} 123}
124 124
125static inline void bcbuf_decr_acks(struct sk_buff *buf) 125static void bcbuf_decr_acks(struct sk_buff *buf)
126{ 126{
127 bcbuf_set_acks(buf, bcbuf_acks(buf) - 1); 127 bcbuf_set_acks(buf, bcbuf_acks(buf) - 1);
128} 128}
@@ -134,7 +134,7 @@ static inline void bcbuf_decr_acks(struct sk_buff *buf)
134 * Called with 'node' locked, bc_lock unlocked 134 * Called with 'node' locked, bc_lock unlocked
135 */ 135 */
136 136
137static inline void bclink_set_gap(struct node *n_ptr) 137static void bclink_set_gap(struct node *n_ptr)
138{ 138{
139 struct sk_buff *buf = n_ptr->bclink.deferred_head; 139 struct sk_buff *buf = n_ptr->bclink.deferred_head;
140 140
@@ -154,7 +154,7 @@ static inline void bclink_set_gap(struct node *n_ptr)
154 * distribute NACKs, but tries to use the same spacing (divide by 16). 154 * distribute NACKs, but tries to use the same spacing (divide by 16).
155 */ 155 */
156 156
157static inline int bclink_ack_allowed(u32 n) 157static int bclink_ack_allowed(u32 n)
158{ 158{
159 return((n % TIPC_MIN_LINK_WIN) == tipc_own_tag); 159 return((n % TIPC_MIN_LINK_WIN) == tipc_own_tag);
160} 160}
@@ -271,7 +271,7 @@ static void bclink_send_nack(struct node *n_ptr)
271 msg_set_bcgap_to(msg, n_ptr->bclink.gap_to); 271 msg_set_bcgap_to(msg, n_ptr->bclink.gap_to);
272 msg_set_bcast_tag(msg, tipc_own_tag); 272 msg_set_bcast_tag(msg, tipc_own_tag);
273 273
274 if (tipc_bearer_send(&bcbearer->bearer, buf, 0)) { 274 if (tipc_bearer_send(&bcbearer->bearer, buf, NULL)) {
275 bcl->stats.sent_nacks++; 275 bcl->stats.sent_nacks++;
276 buf_discard(buf); 276 buf_discard(buf);
277 } else { 277 } else {
@@ -314,7 +314,7 @@ void tipc_bclink_check_gap(struct node *n_ptr, u32 last_sent)
314 * Only tipc_net_lock set. 314 * Only tipc_net_lock set.
315 */ 315 */
316 316
317void tipc_bclink_peek_nack(u32 dest, u32 sender_tag, u32 gap_after, u32 gap_to) 317static void tipc_bclink_peek_nack(u32 dest, u32 sender_tag, u32 gap_after, u32 gap_to)
318{ 318{
319 struct node *n_ptr = tipc_node_find(dest); 319 struct node *n_ptr = tipc_node_find(dest);
320 u32 my_after, my_to; 320 u32 my_after, my_to;
@@ -425,9 +425,9 @@ void tipc_bclink_recv_pkt(struct sk_buff *buf)
425 msg_bcgap_to(msg)); 425 msg_bcgap_to(msg));
426 } else { 426 } else {
427 tipc_bclink_peek_nack(msg_destnode(msg), 427 tipc_bclink_peek_nack(msg_destnode(msg),
428 msg_bcast_tag(msg), 428 msg_bcast_tag(msg),
429 msg_bcgap_after(msg), 429 msg_bcgap_after(msg),
430 msg_bcgap_to(msg)); 430 msg_bcgap_to(msg));
431 } 431 }
432 buf_discard(buf); 432 buf_discard(buf);
433 return; 433 return;
@@ -525,16 +525,18 @@ u32 tipc_bclink_acks_missing(struct node *n_ptr)
525 * Returns 0 if packet sent successfully, non-zero if not 525 * Returns 0 if packet sent successfully, non-zero if not
526 */ 526 */
527 527
528int tipc_bcbearer_send(struct sk_buff *buf, 528static int tipc_bcbearer_send(struct sk_buff *buf,
529 struct tipc_bearer *unused1, 529 struct tipc_bearer *unused1,
530 struct tipc_media_addr *unused2) 530 struct tipc_media_addr *unused2)
531{ 531{
532 static int send_count = 0; 532 static int send_count = 0;
533 533
534 struct node_map remains; 534 struct node_map *remains;
535 struct node_map remains_new; 535 struct node_map *remains_new;
536 struct node_map *remains_tmp;
536 int bp_index; 537 int bp_index;
537 int swap_time; 538 int swap_time;
539 int err;
538 540
539 /* Prepare buffer for broadcasting (if first time trying to send it) */ 541 /* Prepare buffer for broadcasting (if first time trying to send it) */
540 542
@@ -555,7 +557,9 @@ int tipc_bcbearer_send(struct sk_buff *buf,
555 557
556 /* Send buffer over bearers until all targets reached */ 558 /* Send buffer over bearers until all targets reached */
557 559
558 remains = tipc_cltr_bcast_nodes; 560 remains = kmalloc(sizeof(struct node_map), GFP_ATOMIC);
561 remains_new = kmalloc(sizeof(struct node_map), GFP_ATOMIC);
562 *remains = tipc_cltr_bcast_nodes;
559 563
560 for (bp_index = 0; bp_index < MAX_BEARERS; bp_index++) { 564 for (bp_index = 0; bp_index < MAX_BEARERS; bp_index++) {
561 struct bearer *p = bcbearer->bpairs[bp_index].primary; 565 struct bearer *p = bcbearer->bpairs[bp_index].primary;
@@ -564,8 +568,8 @@ int tipc_bcbearer_send(struct sk_buff *buf,
564 if (!p) 568 if (!p)
565 break; /* no more bearers to try */ 569 break; /* no more bearers to try */
566 570
567 tipc_nmap_diff(&remains, &p->nodes, &remains_new); 571 tipc_nmap_diff(remains, &p->nodes, remains_new);
568 if (remains_new.count == remains.count) 572 if (remains_new->count == remains->count)
569 continue; /* bearer pair doesn't add anything */ 573 continue; /* bearer pair doesn't add anything */
570 574
571 if (!p->publ.blocked && 575 if (!p->publ.blocked &&
@@ -583,17 +587,27 @@ swap:
583 bcbearer->bpairs[bp_index].primary = s; 587 bcbearer->bpairs[bp_index].primary = s;
584 bcbearer->bpairs[bp_index].secondary = p; 588 bcbearer->bpairs[bp_index].secondary = p;
585update: 589update:
586 if (remains_new.count == 0) 590 if (remains_new->count == 0) {
587 return TIPC_OK; 591 err = TIPC_OK;
592 goto out;
593 }
588 594
595 /* swap map */
596 remains_tmp = remains;
589 remains = remains_new; 597 remains = remains_new;
598 remains_new = remains_tmp;
590 } 599 }
591 600
592 /* Unable to reach all targets */ 601 /* Unable to reach all targets */
593 602
594 bcbearer->bearer.publ.blocked = 1; 603 bcbearer->bearer.publ.blocked = 1;
595 bcl->stats.bearer_congs++; 604 bcl->stats.bearer_congs++;
596 return ~TIPC_OK; 605 err = ~TIPC_OK;
606
607 out:
608 kfree(remains_new);
609 kfree(remains);
610 return err;
597} 611}
598 612
599/** 613/**