diff options
Diffstat (limited to 'net/tipc/bcast.c')
-rw-r--r-- | net/tipc/bcast.c | 35 |
1 files changed, 28 insertions, 7 deletions
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c index 4609819ea807..15eb74458748 100644 --- a/net/tipc/bcast.c +++ b/net/tipc/bcast.c | |||
@@ -237,14 +237,36 @@ void tipc_bclink_acknowledge(struct tipc_node *n_ptr, u32 acked) | |||
237 | struct sk_buff *next; | 237 | struct sk_buff *next; |
238 | unsigned int released = 0; | 238 | unsigned int released = 0; |
239 | 239 | ||
240 | if (less_eq(acked, n_ptr->bclink.acked)) | ||
241 | return; | ||
242 | |||
243 | spin_lock_bh(&bc_lock); | 240 | spin_lock_bh(&bc_lock); |
244 | 241 | ||
245 | /* Skip over packets that node has previously acknowledged */ | 242 | /* Bail out if tx queue is empty (no clean up is required) */ |
246 | |||
247 | crs = bcl->first_out; | 243 | crs = bcl->first_out; |
244 | if (!crs) | ||
245 | goto exit; | ||
246 | |||
247 | /* Determine which messages need to be acknowledged */ | ||
248 | if (acked == INVALID_LINK_SEQ) { | ||
249 | /* | ||
250 | * Contact with specified node has been lost, so need to | ||
251 | * acknowledge sent messages only (if other nodes still exist) | ||
252 | * or both sent and unsent messages (otherwise) | ||
253 | */ | ||
254 | if (bclink->bcast_nodes.count) | ||
255 | acked = bcl->fsm_msg_cnt; | ||
256 | else | ||
257 | acked = bcl->next_out_no; | ||
258 | } else { | ||
259 | /* | ||
260 | * Bail out if specified sequence number does not correspond | ||
261 | * to a message that has been sent and not yet acknowledged | ||
262 | */ | ||
263 | if (less(acked, buf_seqno(crs)) || | ||
264 | less(bcl->fsm_msg_cnt, acked) || | ||
265 | less_eq(acked, n_ptr->bclink.acked)) | ||
266 | goto exit; | ||
267 | } | ||
268 | |||
269 | /* Skip over packets that node has previously acknowledged */ | ||
248 | while (crs && less_eq(buf_seqno(crs), n_ptr->bclink.acked)) | 270 | while (crs && less_eq(buf_seqno(crs), n_ptr->bclink.acked)) |
249 | crs = crs->next; | 271 | crs = crs->next; |
250 | 272 | ||
@@ -255,8 +277,6 @@ void tipc_bclink_acknowledge(struct tipc_node *n_ptr, u32 acked) | |||
255 | 277 | ||
256 | if (crs != bcl->next_out) | 278 | if (crs != bcl->next_out) |
257 | bcbuf_decr_acks(crs); | 279 | bcbuf_decr_acks(crs); |
258 | else if (bclink->bcast_nodes.count) | ||
259 | break; | ||
260 | else { | 280 | else { |
261 | bcbuf_set_acks(crs, 0); | 281 | bcbuf_set_acks(crs, 0); |
262 | bcl->next_out = next; | 282 | bcl->next_out = next; |
@@ -281,6 +301,7 @@ void tipc_bclink_acknowledge(struct tipc_node *n_ptr, u32 acked) | |||
281 | } | 301 | } |
282 | if (unlikely(released && !list_empty(&bcl->waiting_ports))) | 302 | if (unlikely(released && !list_empty(&bcl->waiting_ports))) |
283 | tipc_link_wakeup_ports(bcl, 0); | 303 | tipc_link_wakeup_ports(bcl, 0); |
304 | exit: | ||
284 | spin_unlock_bh(&bc_lock); | 305 | spin_unlock_bh(&bc_lock); |
285 | } | 306 | } |
286 | 307 | ||