aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
authorAllan Stephens <allan.stephens@windriver.com>2010-08-17 07:00:09 -0400
committerDavid S. Miller <davem@davemloft.net>2010-08-17 20:31:55 -0400
commit5b1f7bdeb698547cc319c7a302a5acf585227a92 (patch)
tree1b86f815e592ead732320574b7a047ccd74e86db /net/tipc
parent7e3e5d0950559d1118dccbdff3c765fffcf04fd5 (diff)
tipc: Fix premature broadcast advertisement by sending node
Prevent a TIPC node from sending out a LINK_STATE message advertising a broadcast message that it is in the process of sending, but has not yet actually sent. Previously, it was possible for a link timeout to occur in between the time the broadcast link updated its "last message sent" counter and the time the broadcast message was passed to the broadcast bearer for transmission. This ensures that the code which issues the LINK_STATE message isn't informed of the new message until the broadcast bearer has had a chance to send it. Note: The "last message sent" value is stored in the "fsm_msg_count" field of the link structure used by the broadcast link. Since the broadcast link doesn't utilize the normal link FSM, this field can be re-used rather than adding a new field to the broadcast link. Signed-off-by: Allan Stephens <allan.stephens@windriver.com> Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc')
-rw-r--r--net/tipc/bcast.c30
1 files changed, 19 insertions, 11 deletions
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
index 42b1737f0dcf..eefdd1a85f4f 100644
--- a/net/tipc/bcast.c
+++ b/net/tipc/bcast.c
@@ -143,6 +143,19 @@ static void bcbuf_decr_acks(struct sk_buff *buf)
143} 143}
144 144
145 145
146static void bclink_set_last_sent(void)
147{
148 if (bcl->next_out)
149 bcl->fsm_msg_cnt = mod(buf_seqno(bcl->next_out) - 1);
150 else
151 bcl->fsm_msg_cnt = mod(bcl->next_out_no - 1);
152}
153
154u32 tipc_bclink_get_last_sent(void)
155{
156 return bcl->fsm_msg_cnt;
157}
158
146/** 159/**
147 * bclink_set_gap - set gap according to contents of current deferred pkt queue 160 * bclink_set_gap - set gap according to contents of current deferred pkt queue
148 * 161 *
@@ -237,8 +250,10 @@ void tipc_bclink_acknowledge(struct tipc_node *n_ptr, u32 acked)
237 250
238 /* Try resolving broadcast link congestion, if necessary */ 251 /* Try resolving broadcast link congestion, if necessary */
239 252
240 if (unlikely(bcl->next_out)) 253 if (unlikely(bcl->next_out)) {
241 tipc_link_push_queue(bcl); 254 tipc_link_push_queue(bcl);
255 bclink_set_last_sent();
256 }
242 if (unlikely(released && !list_empty(&bcl->waiting_ports))) 257 if (unlikely(released && !list_empty(&bcl->waiting_ports)))
243 tipc_link_wakeup_ports(bcl, 0); 258 tipc_link_wakeup_ports(bcl, 0);
244 spin_unlock_bh(&bc_lock); 259 spin_unlock_bh(&bc_lock);
@@ -394,8 +409,10 @@ int tipc_bclink_send_msg(struct sk_buff *buf)
394 res = tipc_link_send_buf(bcl, buf); 409 res = tipc_link_send_buf(bcl, buf);
395 if (unlikely(res == -ELINKCONG)) 410 if (unlikely(res == -ELINKCONG))
396 buf_discard(buf); 411 buf_discard(buf);
397 else 412 else {
398 bcl->stats.sent_info++; 413 bcl->stats.sent_info++;
414 bclink_set_last_sent();
415 }
399 416
400 if (bcl->out_queue_size > bcl->stats.max_queue_sz) 417 if (bcl->out_queue_size > bcl->stats.max_queue_sz)
401 bcl->stats.max_queue_sz = bcl->out_queue_size; 418 bcl->stats.max_queue_sz = bcl->out_queue_size;
@@ -529,15 +546,6 @@ receive:
529 tipc_node_unlock(node); 546 tipc_node_unlock(node);
530} 547}
531 548
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) 549u32 tipc_bclink_acks_missing(struct tipc_node *n_ptr)
542{ 550{
543 return (n_ptr->bclink.supported && 551 return (n_ptr->bclink.supported &&