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.c161
1 files changed, 95 insertions, 66 deletions
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
index 28908f54459e..8eb87b11d100 100644
--- a/net/tipc/bcast.c
+++ b/net/tipc/bcast.c
@@ -46,7 +46,7 @@
46#define BCLINK_WIN_DEFAULT 20 /* bcast link window size (default) */ 46#define BCLINK_WIN_DEFAULT 20 /* bcast link window size (default) */
47 47
48/** 48/**
49 * struct bcbearer_pair - a pair of bearers used by broadcast link 49 * struct tipc_bcbearer_pair - a pair of bearers used by broadcast link
50 * @primary: pointer to primary bearer 50 * @primary: pointer to primary bearer
51 * @secondary: pointer to secondary bearer 51 * @secondary: pointer to secondary bearer
52 * 52 *
@@ -54,13 +54,13 @@
54 * to be paired. 54 * to be paired.
55 */ 55 */
56 56
57struct bcbearer_pair { 57struct tipc_bcbearer_pair {
58 struct tipc_bearer *primary; 58 struct tipc_bearer *primary;
59 struct tipc_bearer *secondary; 59 struct tipc_bearer *secondary;
60}; 60};
61 61
62/** 62/**
63 * struct bcbearer - bearer used by broadcast link 63 * struct tipc_bcbearer - bearer used by broadcast link
64 * @bearer: (non-standard) broadcast bearer structure 64 * @bearer: (non-standard) broadcast bearer structure
65 * @media: (non-standard) broadcast media structure 65 * @media: (non-standard) broadcast media structure
66 * @bpairs: array of bearer pairs 66 * @bpairs: array of bearer pairs
@@ -74,38 +74,40 @@ struct bcbearer_pair {
74 * prevented through use of the spinlock "bc_lock". 74 * prevented through use of the spinlock "bc_lock".
75 */ 75 */
76 76
77struct bcbearer { 77struct tipc_bcbearer {
78 struct tipc_bearer bearer; 78 struct tipc_bearer bearer;
79 struct media media; 79 struct tipc_media media;
80 struct bcbearer_pair bpairs[MAX_BEARERS]; 80 struct tipc_bcbearer_pair bpairs[MAX_BEARERS];
81 struct bcbearer_pair bpairs_temp[TIPC_MAX_LINK_PRI + 1]; 81 struct tipc_bcbearer_pair bpairs_temp[TIPC_MAX_LINK_PRI + 1];
82 struct tipc_node_map remains; 82 struct tipc_node_map remains;
83 struct tipc_node_map remains_new; 83 struct tipc_node_map remains_new;
84}; 84};
85 85
86/** 86/**
87 * struct bclink - link used for broadcast messages 87 * struct tipc_bclink - link used for broadcast messages
88 * @link: (non-standard) broadcast link structure 88 * @link: (non-standard) broadcast link structure
89 * @node: (non-standard) node structure representing b'cast link's peer node 89 * @node: (non-standard) node structure representing b'cast link's peer node
90 * @bcast_nodes: map of broadcast-capable nodes
90 * @retransmit_to: node that most recently requested a retransmit 91 * @retransmit_to: node that most recently requested a retransmit
91 * 92 *
92 * Handles sequence numbering, fragmentation, bundling, etc. 93 * Handles sequence numbering, fragmentation, bundling, etc.
93 */ 94 */
94 95
95struct bclink { 96struct tipc_bclink {
96 struct link link; 97 struct tipc_link link;
97 struct tipc_node node; 98 struct tipc_node node;
99 struct tipc_node_map bcast_nodes;
98 struct tipc_node *retransmit_to; 100 struct tipc_node *retransmit_to;
99}; 101};
100 102
103static struct tipc_bcbearer bcast_bearer;
104static struct tipc_bclink bcast_link;
101 105
102static struct bcbearer *bcbearer; 106static struct tipc_bcbearer *bcbearer = &bcast_bearer;
103static struct bclink *bclink; 107static struct tipc_bclink *bclink = &bcast_link;
104static struct link *bcl; 108static struct tipc_link *bcl = &bcast_link.link;
105static DEFINE_SPINLOCK(bc_lock);
106 109
107/* broadcast-capable node map */ 110static DEFINE_SPINLOCK(bc_lock);
108struct tipc_node_map tipc_bcast_nmap;
109 111
110const char tipc_bclink_name[] = "broadcast-link"; 112const char tipc_bclink_name[] = "broadcast-link";
111 113
@@ -113,11 +115,6 @@ static void tipc_nmap_diff(struct tipc_node_map *nm_a,
113 struct tipc_node_map *nm_b, 115 struct tipc_node_map *nm_b,
114 struct tipc_node_map *nm_diff); 116 struct tipc_node_map *nm_diff);
115 117
116static u32 buf_seqno(struct sk_buff *buf)
117{
118 return msg_seqno(buf_msg(buf));
119}
120
121static u32 bcbuf_acks(struct sk_buff *buf) 118static u32 bcbuf_acks(struct sk_buff *buf)
122{ 119{
123 return (u32)(unsigned long)TIPC_SKB_CB(buf)->handle; 120 return (u32)(unsigned long)TIPC_SKB_CB(buf)->handle;
@@ -133,6 +130,19 @@ static void bcbuf_decr_acks(struct sk_buff *buf)
133 bcbuf_set_acks(buf, bcbuf_acks(buf) - 1); 130 bcbuf_set_acks(buf, bcbuf_acks(buf) - 1);
134} 131}
135 132
133void tipc_bclink_add_node(u32 addr)
134{
135 spin_lock_bh(&bc_lock);
136 tipc_nmap_add(&bclink->bcast_nodes, addr);
137 spin_unlock_bh(&bc_lock);
138}
139
140void tipc_bclink_remove_node(u32 addr)
141{
142 spin_lock_bh(&bc_lock);
143 tipc_nmap_remove(&bclink->bcast_nodes, addr);
144 spin_unlock_bh(&bc_lock);
145}
136 146
137static void bclink_set_last_sent(void) 147static void bclink_set_last_sent(void)
138{ 148{
@@ -222,14 +232,36 @@ void tipc_bclink_acknowledge(struct tipc_node *n_ptr, u32 acked)
222 struct sk_buff *next; 232 struct sk_buff *next;
223 unsigned int released = 0; 233 unsigned int released = 0;
224 234
225 if (less_eq(acked, n_ptr->bclink.acked))
226 return;
227
228 spin_lock_bh(&bc_lock); 235 spin_lock_bh(&bc_lock);
229 236
230 /* Skip over packets that node has previously acknowledged */ 237 /* Bail out if tx queue is empty (no clean up is required) */
231
232 crs = bcl->first_out; 238 crs = bcl->first_out;
239 if (!crs)
240 goto exit;
241
242 /* Determine which messages need to be acknowledged */
243 if (acked == INVALID_LINK_SEQ) {
244 /*
245 * Contact with specified node has been lost, so need to
246 * acknowledge sent messages only (if other nodes still exist)
247 * or both sent and unsent messages (otherwise)
248 */
249 if (bclink->bcast_nodes.count)
250 acked = bcl->fsm_msg_cnt;
251 else
252 acked = bcl->next_out_no;
253 } else {
254 /*
255 * Bail out if specified sequence number does not correspond
256 * to a message that has been sent and not yet acknowledged
257 */
258 if (less(acked, buf_seqno(crs)) ||
259 less(bcl->fsm_msg_cnt, acked) ||
260 less_eq(acked, n_ptr->bclink.acked))
261 goto exit;
262 }
263
264 /* Skip over packets that node has previously acknowledged */
233 while (crs && less_eq(buf_seqno(crs), n_ptr->bclink.acked)) 265 while (crs && less_eq(buf_seqno(crs), n_ptr->bclink.acked))
234 crs = crs->next; 266 crs = crs->next;
235 267
@@ -237,7 +269,15 @@ void tipc_bclink_acknowledge(struct tipc_node *n_ptr, u32 acked)
237 269
238 while (crs && less_eq(buf_seqno(crs), acked)) { 270 while (crs && less_eq(buf_seqno(crs), acked)) {
239 next = crs->next; 271 next = crs->next;
240 bcbuf_decr_acks(crs); 272
273 if (crs != bcl->next_out)
274 bcbuf_decr_acks(crs);
275 else {
276 bcbuf_set_acks(crs, 0);
277 bcl->next_out = next;
278 bclink_set_last_sent();
279 }
280
241 if (bcbuf_acks(crs) == 0) { 281 if (bcbuf_acks(crs) == 0) {
242 bcl->first_out = next; 282 bcl->first_out = next;
243 bcl->out_queue_size--; 283 bcl->out_queue_size--;
@@ -256,6 +296,7 @@ void tipc_bclink_acknowledge(struct tipc_node *n_ptr, u32 acked)
256 } 296 }
257 if (unlikely(released && !list_empty(&bcl->waiting_ports))) 297 if (unlikely(released && !list_empty(&bcl->waiting_ports)))
258 tipc_link_wakeup_ports(bcl, 0); 298 tipc_link_wakeup_ports(bcl, 0);
299exit:
259 spin_unlock_bh(&bc_lock); 300 spin_unlock_bh(&bc_lock);
260} 301}
261 302
@@ -267,7 +308,7 @@ void tipc_bclink_acknowledge(struct tipc_node *n_ptr, u32 acked)
267 308
268static void bclink_send_ack(struct tipc_node *n_ptr) 309static void bclink_send_ack(struct tipc_node *n_ptr)
269{ 310{
270 struct link *l_ptr = n_ptr->active_links[n_ptr->addr & 1]; 311 struct tipc_link *l_ptr = n_ptr->active_links[n_ptr->addr & 1];
271 312
272 if (l_ptr != NULL) 313 if (l_ptr != NULL)
273 tipc_link_send_proto_msg(l_ptr, STATE_MSG, 0, 0, 0, 0, 0); 314 tipc_link_send_proto_msg(l_ptr, STATE_MSG, 0, 0, 0, 0, 0);
@@ -402,13 +443,19 @@ int tipc_bclink_send_msg(struct sk_buff *buf)
402 443
403 spin_lock_bh(&bc_lock); 444 spin_lock_bh(&bc_lock);
404 445
446 if (!bclink->bcast_nodes.count) {
447 res = msg_data_sz(buf_msg(buf));
448 buf_discard(buf);
449 goto exit;
450 }
451
405 res = tipc_link_send_buf(bcl, buf); 452 res = tipc_link_send_buf(bcl, buf);
406 if (likely(res > 0)) 453 if (likely(res >= 0)) {
407 bclink_set_last_sent(); 454 bclink_set_last_sent();
408 455 bcl->stats.queue_sz_counts++;
409 bcl->stats.queue_sz_counts++; 456 bcl->stats.accu_queue_sz += bcl->out_queue_size;
410 bcl->stats.accu_queue_sz += bcl->out_queue_size; 457 }
411 458exit:
412 spin_unlock_bh(&bc_lock); 459 spin_unlock_bh(&bc_lock);
413 return res; 460 return res;
414} 461}
@@ -572,13 +619,13 @@ static int tipc_bcbearer_send(struct sk_buff *buf,
572 if (likely(!msg_non_seq(buf_msg(buf)))) { 619 if (likely(!msg_non_seq(buf_msg(buf)))) {
573 struct tipc_msg *msg; 620 struct tipc_msg *msg;
574 621
575 bcbuf_set_acks(buf, tipc_bcast_nmap.count); 622 bcbuf_set_acks(buf, bclink->bcast_nodes.count);
576 msg = buf_msg(buf); 623 msg = buf_msg(buf);
577 msg_set_non_seq(msg, 1); 624 msg_set_non_seq(msg, 1);
578 msg_set_mc_netid(msg, tipc_net_id); 625 msg_set_mc_netid(msg, tipc_net_id);
579 bcl->stats.sent_info++; 626 bcl->stats.sent_info++;
580 627
581 if (WARN_ON(!tipc_bcast_nmap.count)) { 628 if (WARN_ON(!bclink->bcast_nodes.count)) {
582 dump_stack(); 629 dump_stack();
583 return 0; 630 return 0;
584 } 631 }
@@ -586,7 +633,7 @@ static int tipc_bcbearer_send(struct sk_buff *buf,
586 633
587 /* Send buffer over bearers until all targets reached */ 634 /* Send buffer over bearers until all targets reached */
588 635
589 bcbearer->remains = tipc_bcast_nmap; 636 bcbearer->remains = bclink->bcast_nodes;
590 637
591 for (bp_index = 0; bp_index < MAX_BEARERS; bp_index++) { 638 for (bp_index = 0; bp_index < MAX_BEARERS; bp_index++) {
592 struct tipc_bearer *p = bcbearer->bpairs[bp_index].primary; 639 struct tipc_bearer *p = bcbearer->bpairs[bp_index].primary;
@@ -630,8 +677,8 @@ static int tipc_bcbearer_send(struct sk_buff *buf,
630 677
631void tipc_bcbearer_sort(void) 678void tipc_bcbearer_sort(void)
632{ 679{
633 struct bcbearer_pair *bp_temp = bcbearer->bpairs_temp; 680 struct tipc_bcbearer_pair *bp_temp = bcbearer->bpairs_temp;
634 struct bcbearer_pair *bp_curr; 681 struct tipc_bcbearer_pair *bp_curr;
635 int b_index; 682 int b_index;
636 int pri; 683 int pri;
637 684
@@ -752,25 +799,13 @@ int tipc_bclink_set_queue_limits(u32 limit)
752 return 0; 799 return 0;
753} 800}
754 801
755int tipc_bclink_init(void) 802void tipc_bclink_init(void)
756{ 803{
757 bcbearer = kzalloc(sizeof(*bcbearer), GFP_ATOMIC);
758 bclink = kzalloc(sizeof(*bclink), GFP_ATOMIC);
759 if (!bcbearer || !bclink) {
760 warn("Broadcast link creation failed, no memory\n");
761 kfree(bcbearer);
762 bcbearer = NULL;
763 kfree(bclink);
764 bclink = NULL;
765 return -ENOMEM;
766 }
767
768 INIT_LIST_HEAD(&bcbearer->bearer.cong_links); 804 INIT_LIST_HEAD(&bcbearer->bearer.cong_links);
769 bcbearer->bearer.media = &bcbearer->media; 805 bcbearer->bearer.media = &bcbearer->media;
770 bcbearer->media.send_msg = tipc_bcbearer_send; 806 bcbearer->media.send_msg = tipc_bcbearer_send;
771 sprintf(bcbearer->media.name, "tipc-broadcast"); 807 sprintf(bcbearer->media.name, "tipc-broadcast");
772 808
773 bcl = &bclink->link;
774 INIT_LIST_HEAD(&bcl->waiting_ports); 809 INIT_LIST_HEAD(&bcl->waiting_ports);
775 bcl->next_out_no = 1; 810 bcl->next_out_no = 1;
776 spin_lock_init(&bclink->node.lock); 811 spin_lock_init(&bclink->node.lock);
@@ -780,22 +815,16 @@ int tipc_bclink_init(void)
780 bcl->b_ptr = &bcbearer->bearer; 815 bcl->b_ptr = &bcbearer->bearer;
781 bcl->state = WORKING_WORKING; 816 bcl->state = WORKING_WORKING;
782 strlcpy(bcl->name, tipc_bclink_name, TIPC_MAX_LINK_NAME); 817 strlcpy(bcl->name, tipc_bclink_name, TIPC_MAX_LINK_NAME);
783
784 return 0;
785} 818}
786 819
787void tipc_bclink_stop(void) 820void tipc_bclink_stop(void)
788{ 821{
789 spin_lock_bh(&bc_lock); 822 spin_lock_bh(&bc_lock);
790 if (bcbearer) { 823 tipc_link_stop(bcl);
791 tipc_link_stop(bcl);
792 bcl = NULL;
793 kfree(bclink);
794 bclink = NULL;
795 kfree(bcbearer);
796 bcbearer = NULL;
797 }
798 spin_unlock_bh(&bc_lock); 824 spin_unlock_bh(&bc_lock);
825
826 memset(bclink, 0, sizeof(*bclink));
827 memset(bcbearer, 0, sizeof(*bcbearer));
799} 828}
800 829
801 830
@@ -864,9 +893,9 @@ static void tipc_nmap_diff(struct tipc_node_map *nm_a,
864 * tipc_port_list_add - add a port to a port list, ensuring no duplicates 893 * tipc_port_list_add - add a port to a port list, ensuring no duplicates
865 */ 894 */
866 895
867void tipc_port_list_add(struct port_list *pl_ptr, u32 port) 896void tipc_port_list_add(struct tipc_port_list *pl_ptr, u32 port)
868{ 897{
869 struct port_list *item = pl_ptr; 898 struct tipc_port_list *item = pl_ptr;
870 int i; 899 int i;
871 int item_sz = PLSIZE; 900 int item_sz = PLSIZE;
872 int cnt = pl_ptr->count; 901 int cnt = pl_ptr->count;
@@ -898,10 +927,10 @@ void tipc_port_list_add(struct port_list *pl_ptr, u32 port)
898 * 927 *
899 */ 928 */
900 929
901void tipc_port_list_free(struct port_list *pl_ptr) 930void tipc_port_list_free(struct tipc_port_list *pl_ptr)
902{ 931{
903 struct port_list *item; 932 struct tipc_port_list *item;
904 struct port_list *next; 933 struct tipc_port_list *next;
905 934
906 for (item = pl_ptr->next; item; item = next) { 935 for (item = pl_ptr->next; item; item = next) {
907 next = item->next; 936 next = item->next;