diff options
Diffstat (limited to 'net')
| -rw-r--r-- | net/tipc/bcast.c | 30 |
1 files changed, 22 insertions, 8 deletions
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c index 3d37fa2c1464..2c4ecbe50082 100644 --- a/net/tipc/bcast.c +++ b/net/tipc/bcast.c | |||
| @@ -531,10 +531,12 @@ static int tipc_bcbearer_send(struct sk_buff *buf, | |||
| 531 | { | 531 | { |
| 532 | static int send_count = 0; | 532 | static int send_count = 0; |
| 533 | 533 | ||
| 534 | struct node_map remains; | 534 | struct node_map *remains; |
| 535 | struct node_map remains_new; | 535 | struct node_map *remains_new; |
| 536 | struct node_map *remains_tmp; | ||
| 536 | int bp_index; | 537 | int bp_index; |
| 537 | int swap_time; | 538 | int swap_time; |
| 539 | int err; | ||
| 538 | 540 | ||
| 539 | /* Prepare buffer for broadcasting (if first time trying to send it) */ | 541 | /* Prepare buffer for broadcasting (if first time trying to send it) */ |
| 540 | 542 | ||
| @@ -555,7 +557,9 @@ static int tipc_bcbearer_send(struct sk_buff *buf, | |||
| 555 | 557 | ||
| 556 | /* Send buffer over bearers until all targets reached */ | 558 | /* Send buffer over bearers until all targets reached */ |
| 557 | 559 | ||
| 558 | remains = tipc_cltr_bcast_nodes; | 560 | remains = kmalloc(sizeof(struct node_map), GFP_ATOMIC); |
| 561 | remains_new = kmalloc(sizeof(struct node_map), GFP_ATOMIC); | ||
| 562 | *remains = tipc_cltr_bcast_nodes; | ||
| 559 | 563 | ||
| 560 | for (bp_index = 0; bp_index < MAX_BEARERS; bp_index++) { | 564 | for (bp_index = 0; bp_index < MAX_BEARERS; bp_index++) { |
| 561 | struct bearer *p = bcbearer->bpairs[bp_index].primary; | 565 | struct bearer *p = bcbearer->bpairs[bp_index].primary; |
| @@ -564,8 +568,8 @@ static int tipc_bcbearer_send(struct sk_buff *buf, | |||
| 564 | if (!p) | 568 | if (!p) |
| 565 | break; /* no more bearers to try */ | 569 | break; /* no more bearers to try */ |
| 566 | 570 | ||
| 567 | tipc_nmap_diff(&remains, &p->nodes, &remains_new); | 571 | tipc_nmap_diff(remains, &p->nodes, remains_new); |
| 568 | if (remains_new.count == remains.count) | 572 | if (remains_new->count == remains->count) |
| 569 | continue; /* bearer pair doesn't add anything */ | 573 | continue; /* bearer pair doesn't add anything */ |
| 570 | 574 | ||
| 571 | if (!p->publ.blocked && | 575 | if (!p->publ.blocked && |
| @@ -583,17 +587,27 @@ swap: | |||
| 583 | bcbearer->bpairs[bp_index].primary = s; | 587 | bcbearer->bpairs[bp_index].primary = s; |
| 584 | bcbearer->bpairs[bp_index].secondary = p; | 588 | bcbearer->bpairs[bp_index].secondary = p; |
| 585 | update: | 589 | update: |
| 586 | if (remains_new.count == 0) | 590 | if (remains_new->count == 0) { |
| 587 | return TIPC_OK; | 591 | err = TIPC_OK; |
| 592 | goto out; | ||
| 593 | } | ||
| 588 | 594 | ||
| 595 | /* swap map */ | ||
| 596 | remains_tmp = remains; | ||
| 589 | remains = remains_new; | 597 | remains = remains_new; |
| 598 | remains_new = remains_tmp; | ||
| 590 | } | 599 | } |
| 591 | 600 | ||
| 592 | /* Unable to reach all targets */ | 601 | /* Unable to reach all targets */ |
| 593 | 602 | ||
| 594 | bcbearer->bearer.publ.blocked = 1; | 603 | bcbearer->bearer.publ.blocked = 1; |
| 595 | bcl->stats.bearer_congs++; | 604 | bcl->stats.bearer_congs++; |
| 596 | return ~TIPC_OK; | 605 | err = ~TIPC_OK; |
| 606 | |||
| 607 | out: | ||
| 608 | kfree(remains_new); | ||
| 609 | kfree(remains); | ||
| 610 | return err; | ||
| 597 | } | 611 | } |
| 598 | 612 | ||
| 599 | /** | 613 | /** |
