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 | ||
