diff options
Diffstat (limited to 'net/tipc/bcast.c')
-rw-r--r-- | net/tipc/bcast.c | 58 |
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; | |||
107 | char tipc_bclink_name[] = "multicast-link"; | 107 | char tipc_bclink_name[] = "multicast-link"; |
108 | 108 | ||
109 | 109 | ||
110 | static inline u32 buf_seqno(struct sk_buff *buf) | 110 | static 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 | ||
115 | static inline u32 bcbuf_acks(struct sk_buff *buf) | 115 | static 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 | ||
120 | static inline void bcbuf_set_acks(struct sk_buff *buf, u32 acks) | 120 | static 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 | ||
125 | static inline void bcbuf_decr_acks(struct sk_buff *buf) | 125 | static 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 | ||
137 | static inline void bclink_set_gap(struct node *n_ptr) | 137 | static 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 | ||
157 | static inline int bclink_ack_allowed(u32 n) | 157 | static 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 | ||
317 | void tipc_bclink_peek_nack(u32 dest, u32 sender_tag, u32 gap_after, u32 gap_to) | 317 | static 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 | ||
528 | int tipc_bcbearer_send(struct sk_buff *buf, | 528 | static 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; |
585 | update: | 589 | update: |
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 | /** |