aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/bcast.c
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /net/tipc/bcast.c
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'net/tipc/bcast.c')
-rw-r--r--net/tipc/bcast.c168
1 files changed, 74 insertions, 94 deletions
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
index a008c6689305..fa68d1e9ff4b 100644
--- a/net/tipc/bcast.c
+++ b/net/tipc/bcast.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright (c) 2004-2006, Ericsson AB 4 * Copyright (c) 2004-2006, Ericsson AB
5 * Copyright (c) 2004, Intel Corporation. 5 * Copyright (c) 2004, Intel Corporation.
6 * Copyright (c) 2005, Wind River Systems 6 * Copyright (c) 2005, 2010-2011, Wind River Systems
7 * All rights reserved. 7 * All rights reserved.
8 * 8 *
9 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
@@ -36,32 +36,14 @@
36 */ 36 */
37 37
38#include "core.h" 38#include "core.h"
39#include "msg.h"
40#include "dbg.h"
41#include "link.h" 39#include "link.h"
42#include "net.h"
43#include "node.h"
44#include "port.h" 40#include "port.h"
45#include "addr.h"
46#include "node_subscr.h"
47#include "name_distr.h"
48#include "bearer.h"
49#include "name_table.h"
50#include "bcast.h" 41#include "bcast.h"
51 42
52#define MAX_PKT_DEFAULT_MCAST 1500 /* bcast link max packet size (fixed) */ 43#define MAX_PKT_DEFAULT_MCAST 1500 /* bcast link max packet size (fixed) */
53 44
54#define BCLINK_WIN_DEFAULT 20 /* bcast link window size (default) */ 45#define BCLINK_WIN_DEFAULT 20 /* bcast link window size (default) */
55 46
56#define BCLINK_LOG_BUF_SIZE 0
57
58/*
59 * Loss rate for incoming broadcast frames; used to test retransmission code.
60 * Set to N to cause every N'th frame to be discarded; 0 => don't discard any.
61 */
62
63#define TIPC_BCAST_LOSS_RATE 0
64
65/** 47/**
66 * struct bcbearer_pair - a pair of bearers used by broadcast link 48 * struct bcbearer_pair - a pair of bearers used by broadcast link
67 * @primary: pointer to primary bearer 49 * @primary: pointer to primary bearer
@@ -72,8 +54,8 @@
72 */ 54 */
73 55
74struct bcbearer_pair { 56struct bcbearer_pair {
75 struct bearer *primary; 57 struct tipc_bearer *primary;
76 struct bearer *secondary; 58 struct tipc_bearer *secondary;
77}; 59};
78 60
79/** 61/**
@@ -92,7 +74,7 @@ struct bcbearer_pair {
92 */ 74 */
93 75
94struct bcbearer { 76struct bcbearer {
95 struct bearer bearer; 77 struct tipc_bearer bearer;
96 struct media media; 78 struct media media;
97 struct bcbearer_pair bpairs[MAX_BEARERS]; 79 struct bcbearer_pair bpairs[MAX_BEARERS];
98 struct bcbearer_pair bpairs_temp[TIPC_MAX_LINK_PRI + 1]; 80 struct bcbearer_pair bpairs_temp[TIPC_MAX_LINK_PRI + 1];
@@ -104,6 +86,7 @@ struct bcbearer {
104 * struct bclink - link used for broadcast messages 86 * struct bclink - link used for broadcast messages
105 * @link: (non-standard) broadcast link structure 87 * @link: (non-standard) broadcast link structure
106 * @node: (non-standard) node structure representing b'cast link's peer node 88 * @node: (non-standard) node structure representing b'cast link's peer node
89 * @retransmit_to: node that most recently requested a retransmit
107 * 90 *
108 * Handles sequence numbering, fragmentation, bundling, etc. 91 * Handles sequence numbering, fragmentation, bundling, etc.
109 */ 92 */
@@ -111,16 +94,23 @@ struct bcbearer {
111struct bclink { 94struct bclink {
112 struct link link; 95 struct link link;
113 struct tipc_node node; 96 struct tipc_node node;
97 struct tipc_node *retransmit_to;
114}; 98};
115 99
116 100
117static struct bcbearer *bcbearer = NULL; 101static struct bcbearer *bcbearer;
118static struct bclink *bclink = NULL; 102static struct bclink *bclink;
119static struct link *bcl = NULL; 103static struct link *bcl;
120static DEFINE_SPINLOCK(bc_lock); 104static DEFINE_SPINLOCK(bc_lock);
121 105
106/* broadcast-capable node map */
107struct tipc_node_map tipc_bcast_nmap;
108
122const char tipc_bclink_name[] = "broadcast-link"; 109const char tipc_bclink_name[] = "broadcast-link";
123 110
111static void tipc_nmap_diff(struct tipc_node_map *nm_a,
112 struct tipc_node_map *nm_b,
113 struct tipc_node_map *nm_diff);
124 114
125static u32 buf_seqno(struct sk_buff *buf) 115static u32 buf_seqno(struct sk_buff *buf)
126{ 116{
@@ -143,6 +133,19 @@ static void bcbuf_decr_acks(struct sk_buff *buf)
143} 133}
144 134
145 135
136static void bclink_set_last_sent(void)
137{
138 if (bcl->next_out)
139 bcl->fsm_msg_cnt = mod(buf_seqno(bcl->next_out) - 1);
140 else
141 bcl->fsm_msg_cnt = mod(bcl->next_out_no - 1);
142}
143
144u32 tipc_bclink_get_last_sent(void)
145{
146 return bcl->fsm_msg_cnt;
147}
148
146/** 149/**
147 * bclink_set_gap - set gap according to contents of current deferred pkt queue 150 * bclink_set_gap - set gap according to contents of current deferred pkt queue
148 * 151 *
@@ -171,11 +174,22 @@ static void bclink_set_gap(struct tipc_node *n_ptr)
171 174
172static int bclink_ack_allowed(u32 n) 175static int bclink_ack_allowed(u32 n)
173{ 176{
174 return((n % TIPC_MIN_LINK_WIN) == tipc_own_tag); 177 return (n % TIPC_MIN_LINK_WIN) == tipc_own_tag;
175} 178}
176 179
177 180
178/** 181/**
182 * tipc_bclink_retransmit_to - get most recent node to request retransmission
183 *
184 * Called with bc_lock locked
185 */
186
187struct tipc_node *tipc_bclink_retransmit_to(void)
188{
189 return bclink->retransmit_to;
190}
191
192/**
179 * bclink_retransmit_pkt - retransmit broadcast packets 193 * bclink_retransmit_pkt - retransmit broadcast packets
180 * @after: sequence number of last packet to *not* retransmit 194 * @after: sequence number of last packet to *not* retransmit
181 * @to: sequence number of last packet to retransmit 195 * @to: sequence number of last packet to retransmit
@@ -188,9 +202,8 @@ static void bclink_retransmit_pkt(u32 after, u32 to)
188 struct sk_buff *buf; 202 struct sk_buff *buf;
189 203
190 buf = bcl->first_out; 204 buf = bcl->first_out;
191 while (buf && less_eq(buf_seqno(buf), after)) { 205 while (buf && less_eq(buf_seqno(buf), after))
192 buf = buf->next; 206 buf = buf->next;
193 }
194 tipc_link_retransmit(bcl, buf, mod(to - after)); 207 tipc_link_retransmit(bcl, buf, mod(to - after));
195} 208}
196 209
@@ -216,9 +229,8 @@ void tipc_bclink_acknowledge(struct tipc_node *n_ptr, u32 acked)
216 /* Skip over packets that node has previously acknowledged */ 229 /* Skip over packets that node has previously acknowledged */
217 230
218 crs = bcl->first_out; 231 crs = bcl->first_out;
219 while (crs && less_eq(buf_seqno(crs), n_ptr->bclink.acked)) { 232 while (crs && less_eq(buf_seqno(crs), n_ptr->bclink.acked))
220 crs = crs->next; 233 crs = crs->next;
221 }
222 234
223 /* Update packets that node is now acknowledging */ 235 /* Update packets that node is now acknowledging */
224 236
@@ -237,8 +249,10 @@ void tipc_bclink_acknowledge(struct tipc_node *n_ptr, u32 acked)
237 249
238 /* Try resolving broadcast link congestion, if necessary */ 250 /* Try resolving broadcast link congestion, if necessary */
239 251
240 if (unlikely(bcl->next_out)) 252 if (unlikely(bcl->next_out)) {
241 tipc_link_push_queue(bcl); 253 tipc_link_push_queue(bcl);
254 bclink_set_last_sent();
255 }
242 if (unlikely(released && !list_empty(&bcl->waiting_ports))) 256 if (unlikely(released && !list_empty(&bcl->waiting_ports)))
243 tipc_link_wakeup_ports(bcl, 0); 257 tipc_link_wakeup_ports(bcl, 0);
244 spin_unlock_bh(&bc_lock); 258 spin_unlock_bh(&bc_lock);
@@ -272,11 +286,12 @@ static void bclink_send_nack(struct tipc_node *n_ptr)
272 if (!less(n_ptr->bclink.gap_after, n_ptr->bclink.gap_to)) 286 if (!less(n_ptr->bclink.gap_after, n_ptr->bclink.gap_to))
273 return; 287 return;
274 288
275 buf = buf_acquire(INT_H_SIZE); 289 buf = tipc_buf_acquire(INT_H_SIZE);
276 if (buf) { 290 if (buf) {
277 msg = buf_msg(buf); 291 msg = buf_msg(buf);
278 tipc_msg_init(msg, BCAST_PROTOCOL, STATE_MSG, 292 tipc_msg_init(msg, BCAST_PROTOCOL, STATE_MSG,
279 INT_H_SIZE, n_ptr->addr); 293 INT_H_SIZE, n_ptr->addr);
294 msg_set_non_seq(msg, 1);
280 msg_set_mc_netid(msg, tipc_net_id); 295 msg_set_mc_netid(msg, tipc_net_id);
281 msg_set_bcast_ack(msg, mod(n_ptr->bclink.last_in)); 296 msg_set_bcast_ack(msg, mod(n_ptr->bclink.last_in));
282 msg_set_bcgap_after(msg, n_ptr->bclink.gap_after); 297 msg_set_bcgap_after(msg, n_ptr->bclink.gap_after);
@@ -392,13 +407,9 @@ int tipc_bclink_send_msg(struct sk_buff *buf)
392 spin_lock_bh(&bc_lock); 407 spin_lock_bh(&bc_lock);
393 408
394 res = tipc_link_send_buf(bcl, buf); 409 res = tipc_link_send_buf(bcl, buf);
395 if (unlikely(res == -ELINKCONG)) 410 if (likely(res > 0))
396 buf_discard(buf); 411 bclink_set_last_sent();
397 else
398 bcl->stats.sent_info++;
399 412
400 if (bcl->out_queue_size > bcl->stats.max_queue_sz)
401 bcl->stats.max_queue_sz = bcl->out_queue_size;
402 bcl->stats.queue_sz_counts++; 413 bcl->stats.queue_sz_counts++;
403 bcl->stats.accu_queue_sz += bcl->out_queue_size; 414 bcl->stats.accu_queue_sz += bcl->out_queue_size;
404 415
@@ -414,17 +425,12 @@ int tipc_bclink_send_msg(struct sk_buff *buf)
414 425
415void tipc_bclink_recv_pkt(struct sk_buff *buf) 426void tipc_bclink_recv_pkt(struct sk_buff *buf)
416{ 427{
417#if (TIPC_BCAST_LOSS_RATE)
418 static int rx_count = 0;
419#endif
420 struct tipc_msg *msg = buf_msg(buf); 428 struct tipc_msg *msg = buf_msg(buf);
421 struct tipc_node* node = tipc_node_find(msg_prevnode(msg)); 429 struct tipc_node *node = tipc_node_find(msg_prevnode(msg));
422 u32 next_in; 430 u32 next_in;
423 u32 seqno; 431 u32 seqno;
424 struct sk_buff *deferred; 432 struct sk_buff *deferred;
425 433
426 msg_dbg(msg, "<BC<<<");
427
428 if (unlikely(!node || !tipc_node_is_up(node) || !node->bclink.supported || 434 if (unlikely(!node || !tipc_node_is_up(node) || !node->bclink.supported ||
429 (msg_mc_netid(msg) != tipc_net_id))) { 435 (msg_mc_netid(msg) != tipc_net_id))) {
430 buf_discard(buf); 436 buf_discard(buf);
@@ -432,17 +438,15 @@ void tipc_bclink_recv_pkt(struct sk_buff *buf)
432 } 438 }
433 439
434 if (unlikely(msg_user(msg) == BCAST_PROTOCOL)) { 440 if (unlikely(msg_user(msg) == BCAST_PROTOCOL)) {
435 msg_dbg(msg, "<BCNACK<<<");
436 if (msg_destnode(msg) == tipc_own_addr) { 441 if (msg_destnode(msg) == tipc_own_addr) {
437 tipc_node_lock(node); 442 tipc_node_lock(node);
438 tipc_bclink_acknowledge(node, msg_bcast_ack(msg)); 443 tipc_bclink_acknowledge(node, msg_bcast_ack(msg));
439 tipc_node_unlock(node); 444 tipc_node_unlock(node);
440 spin_lock_bh(&bc_lock); 445 spin_lock_bh(&bc_lock);
441 bcl->stats.recv_nacks++; 446 bcl->stats.recv_nacks++;
442 bcl->owner->next = node; /* remember requestor */ 447 bclink->retransmit_to = node;
443 bclink_retransmit_pkt(msg_bcgap_after(msg), 448 bclink_retransmit_pkt(msg_bcgap_after(msg),
444 msg_bcgap_to(msg)); 449 msg_bcgap_to(msg));
445 bcl->owner->next = NULL;
446 spin_unlock_bh(&bc_lock); 450 spin_unlock_bh(&bc_lock);
447 } else { 451 } else {
448 tipc_bclink_peek_nack(msg_destnode(msg), 452 tipc_bclink_peek_nack(msg_destnode(msg),
@@ -454,14 +458,6 @@ void tipc_bclink_recv_pkt(struct sk_buff *buf)
454 return; 458 return;
455 } 459 }
456 460
457#if (TIPC_BCAST_LOSS_RATE)
458 if (++rx_count == TIPC_BCAST_LOSS_RATE) {
459 rx_count = 0;
460 buf_discard(buf);
461 return;
462 }
463#endif
464
465 tipc_node_lock(node); 461 tipc_node_lock(node);
466receive: 462receive:
467 deferred = node->bclink.deferred_head; 463 deferred = node->bclink.deferred_head;
@@ -529,15 +525,6 @@ receive:
529 tipc_node_unlock(node); 525 tipc_node_unlock(node);
530} 526}
531 527
532u32 tipc_bclink_get_last_sent(void)
533{
534 u32 last_sent = mod(bcl->next_out_no - 1);
535
536 if (bcl->next_out)
537 last_sent = mod(buf_seqno(bcl->next_out) - 1);
538 return last_sent;
539}
540
541u32 tipc_bclink_acks_missing(struct tipc_node *n_ptr) 528u32 tipc_bclink_acks_missing(struct tipc_node *n_ptr)
542{ 529{
543 return (n_ptr->bclink.supported && 530 return (n_ptr->bclink.supported &&
@@ -565,20 +552,21 @@ static int tipc_bcbearer_send(struct sk_buff *buf,
565 if (likely(!msg_non_seq(buf_msg(buf)))) { 552 if (likely(!msg_non_seq(buf_msg(buf)))) {
566 struct tipc_msg *msg; 553 struct tipc_msg *msg;
567 554
568 assert(tipc_cltr_bcast_nodes.count != 0); 555 assert(tipc_bcast_nmap.count != 0);
569 bcbuf_set_acks(buf, tipc_cltr_bcast_nodes.count); 556 bcbuf_set_acks(buf, tipc_bcast_nmap.count);
570 msg = buf_msg(buf); 557 msg = buf_msg(buf);
571 msg_set_non_seq(msg, 1); 558 msg_set_non_seq(msg, 1);
572 msg_set_mc_netid(msg, tipc_net_id); 559 msg_set_mc_netid(msg, tipc_net_id);
560 bcl->stats.sent_info++;
573 } 561 }
574 562
575 /* Send buffer over bearers until all targets reached */ 563 /* Send buffer over bearers until all targets reached */
576 564
577 bcbearer->remains = tipc_cltr_bcast_nodes; 565 bcbearer->remains = tipc_bcast_nmap;
578 566
579 for (bp_index = 0; bp_index < MAX_BEARERS; bp_index++) { 567 for (bp_index = 0; bp_index < MAX_BEARERS; bp_index++) {
580 struct bearer *p = bcbearer->bpairs[bp_index].primary; 568 struct tipc_bearer *p = bcbearer->bpairs[bp_index].primary;
581 struct bearer *s = bcbearer->bpairs[bp_index].secondary; 569 struct tipc_bearer *s = bcbearer->bpairs[bp_index].secondary;
582 570
583 if (!p) 571 if (!p)
584 break; /* no more bearers to try */ 572 break; /* no more bearers to try */
@@ -587,11 +575,11 @@ static int tipc_bcbearer_send(struct sk_buff *buf,
587 if (bcbearer->remains_new.count == bcbearer->remains.count) 575 if (bcbearer->remains_new.count == bcbearer->remains.count)
588 continue; /* bearer pair doesn't add anything */ 576 continue; /* bearer pair doesn't add anything */
589 577
590 if (p->publ.blocked || 578 if (p->blocked ||
591 p->media->send_msg(buf, &p->publ, &p->media->bcast_addr)) { 579 p->media->send_msg(buf, p, &p->media->bcast_addr)) {
592 /* unable to send on primary bearer */ 580 /* unable to send on primary bearer */
593 if (!s || s->publ.blocked || 581 if (!s || s->blocked ||
594 s->media->send_msg(buf, &s->publ, 582 s->media->send_msg(buf, s,
595 &s->media->bcast_addr)) { 583 &s->media->bcast_addr)) {
596 /* unable to send on either bearer */ 584 /* unable to send on either bearer */
597 continue; 585 continue;
@@ -609,11 +597,13 @@ static int tipc_bcbearer_send(struct sk_buff *buf,
609 bcbearer->remains = bcbearer->remains_new; 597 bcbearer->remains = bcbearer->remains_new;
610 } 598 }
611 599
612 /* Unable to reach all targets */ 600 /*
601 * Unable to reach all targets (indicate success, since currently
602 * there isn't code in place to properly block & unblock the
603 * pseudo-bearer used by the broadcast link)
604 */
613 605
614 bcbearer->bearer.publ.blocked = 1; 606 return TIPC_OK;
615 bcl->stats.bearer_congs++;
616 return 1;
617} 607}
618 608
619/** 609/**
@@ -634,7 +624,7 @@ void tipc_bcbearer_sort(void)
634 memset(bp_temp, 0, sizeof(bcbearer->bpairs_temp)); 624 memset(bp_temp, 0, sizeof(bcbearer->bpairs_temp));
635 625
636 for (b_index = 0; b_index < MAX_BEARERS; b_index++) { 626 for (b_index = 0; b_index < MAX_BEARERS; b_index++) {
637 struct bearer *b = &tipc_bearers[b_index]; 627 struct tipc_bearer *b = &tipc_bearers[b_index];
638 628
639 if (!b->active || !b->nodes.count) 629 if (!b->active || !b->nodes.count)
640 continue; 630 continue;
@@ -683,12 +673,12 @@ void tipc_bcbearer_sort(void)
683 673
684void tipc_bcbearer_push(void) 674void tipc_bcbearer_push(void)
685{ 675{
686 struct bearer *b_ptr; 676 struct tipc_bearer *b_ptr;
687 677
688 spin_lock_bh(&bc_lock); 678 spin_lock_bh(&bc_lock);
689 b_ptr = &bcbearer->bearer; 679 b_ptr = &bcbearer->bearer;
690 if (b_ptr->publ.blocked) { 680 if (b_ptr->blocked) {
691 b_ptr->publ.blocked = 0; 681 b_ptr->blocked = 0;
692 tipc_bearer_lock_push(b_ptr); 682 tipc_bearer_lock_push(b_ptr);
693 } 683 }
694 spin_unlock_bh(&bc_lock); 684 spin_unlock_bh(&bc_lock);
@@ -770,7 +760,6 @@ int tipc_bclink_init(void)
770 bcbearer = kzalloc(sizeof(*bcbearer), GFP_ATOMIC); 760 bcbearer = kzalloc(sizeof(*bcbearer), GFP_ATOMIC);
771 bclink = kzalloc(sizeof(*bclink), GFP_ATOMIC); 761 bclink = kzalloc(sizeof(*bclink), GFP_ATOMIC);
772 if (!bcbearer || !bclink) { 762 if (!bcbearer || !bclink) {
773 nomem:
774 warn("Multicast link creation failed, no memory\n"); 763 warn("Multicast link creation failed, no memory\n");
775 kfree(bcbearer); 764 kfree(bcbearer);
776 bcbearer = NULL; 765 bcbearer = NULL;
@@ -795,14 +784,6 @@ int tipc_bclink_init(void)
795 bcl->state = WORKING_WORKING; 784 bcl->state = WORKING_WORKING;
796 strlcpy(bcl->name, tipc_bclink_name, TIPC_MAX_LINK_NAME); 785 strlcpy(bcl->name, tipc_bclink_name, TIPC_MAX_LINK_NAME);
797 786
798 if (BCLINK_LOG_BUF_SIZE) {
799 char *pb = kmalloc(BCLINK_LOG_BUF_SIZE, GFP_ATOMIC);
800
801 if (!pb)
802 goto nomem;
803 tipc_printbuf_init(&bcl->print_buf, pb, BCLINK_LOG_BUF_SIZE);
804 }
805
806 return 0; 787 return 0;
807} 788}
808 789
@@ -811,8 +792,6 @@ void tipc_bclink_stop(void)
811 spin_lock_bh(&bc_lock); 792 spin_lock_bh(&bc_lock);
812 if (bcbearer) { 793 if (bcbearer) {
813 tipc_link_stop(bcl); 794 tipc_link_stop(bcl);
814 if (BCLINK_LOG_BUF_SIZE)
815 kfree(bcl->print_buf.buf);
816 bcl = NULL; 795 bcl = NULL;
817 kfree(bclink); 796 kfree(bclink);
818 bclink = NULL; 797 bclink = NULL;
@@ -862,8 +841,9 @@ void tipc_nmap_remove(struct tipc_node_map *nm_ptr, u32 node)
862 * @nm_diff: output node map A-B (i.e. nodes of A that are not in B) 841 * @nm_diff: output node map A-B (i.e. nodes of A that are not in B)
863 */ 842 */
864 843
865void tipc_nmap_diff(struct tipc_node_map *nm_a, struct tipc_node_map *nm_b, 844static void tipc_nmap_diff(struct tipc_node_map *nm_a,
866 struct tipc_node_map *nm_diff) 845 struct tipc_node_map *nm_b,
846 struct tipc_node_map *nm_diff)
867{ 847{
868 int stop = ARRAY_SIZE(nm_a->map); 848 int stop = ARRAY_SIZE(nm_a->map);
869 int w; 849 int w;