diff options
-rw-r--r-- | net/tipc/bcast.c | 41 |
1 files changed, 17 insertions, 24 deletions
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c index 1633ef201df9..54128040a124 100644 --- a/net/tipc/bcast.c +++ b/net/tipc/bcast.c | |||
@@ -81,7 +81,14 @@ struct bcbearer_pair { | |||
81 | * @bearer: (non-standard) broadcast bearer structure | 81 | * @bearer: (non-standard) broadcast bearer structure |
82 | * @media: (non-standard) broadcast media structure | 82 | * @media: (non-standard) broadcast media structure |
83 | * @bpairs: array of bearer pairs | 83 | * @bpairs: array of bearer pairs |
84 | * @bpairs_temp: array of bearer pairs used during creation of "bpairs" | 84 | * @bpairs_temp: temporary array of bearer pairs used by tipc_bcbearer_sort() |
85 | * @remains: temporary node map used by tipc_bcbearer_send() | ||
86 | * @remains_new: temporary node map used tipc_bcbearer_send() | ||
87 | * | ||
88 | * Note: The fields labelled "temporary" are incorporated into the bearer | ||
89 | * to avoid consuming potentially limited stack space through the use of | ||
90 | * large local variables within multicast routines. Concurrent access is | ||
91 | * prevented through use of the spinlock "bc_lock". | ||
85 | */ | 92 | */ |
86 | 93 | ||
87 | struct bcbearer { | 94 | struct bcbearer { |
@@ -89,6 +96,8 @@ struct bcbearer { | |||
89 | struct media media; | 96 | struct media media; |
90 | struct bcbearer_pair bpairs[MAX_BEARERS]; | 97 | struct bcbearer_pair bpairs[MAX_BEARERS]; |
91 | struct bcbearer_pair bpairs_temp[TIPC_MAX_LINK_PRI + 1]; | 98 | struct bcbearer_pair bpairs_temp[TIPC_MAX_LINK_PRI + 1]; |
99 | struct node_map remains; | ||
100 | struct node_map remains_new; | ||
92 | }; | 101 | }; |
93 | 102 | ||
94 | /** | 103 | /** |
@@ -551,12 +560,8 @@ static int tipc_bcbearer_send(struct sk_buff *buf, | |||
551 | { | 560 | { |
552 | static int send_count = 0; | 561 | static int send_count = 0; |
553 | 562 | ||
554 | struct node_map *remains; | ||
555 | struct node_map *remains_new; | ||
556 | struct node_map *remains_tmp; | ||
557 | int bp_index; | 563 | int bp_index; |
558 | int swap_time; | 564 | int swap_time; |
559 | int err; | ||
560 | 565 | ||
561 | /* Prepare buffer for broadcasting (if first time trying to send it) */ | 566 | /* Prepare buffer for broadcasting (if first time trying to send it) */ |
562 | 567 | ||
@@ -577,9 +582,7 @@ static int tipc_bcbearer_send(struct sk_buff *buf, | |||
577 | 582 | ||
578 | /* Send buffer over bearers until all targets reached */ | 583 | /* Send buffer over bearers until all targets reached */ |
579 | 584 | ||
580 | remains = kmalloc(sizeof(struct node_map), GFP_ATOMIC); | 585 | bcbearer->remains = tipc_cltr_bcast_nodes; |
581 | remains_new = kmalloc(sizeof(struct node_map), GFP_ATOMIC); | ||
582 | *remains = tipc_cltr_bcast_nodes; | ||
583 | 586 | ||
584 | for (bp_index = 0; bp_index < MAX_BEARERS; bp_index++) { | 587 | for (bp_index = 0; bp_index < MAX_BEARERS; bp_index++) { |
585 | struct bearer *p = bcbearer->bpairs[bp_index].primary; | 588 | struct bearer *p = bcbearer->bpairs[bp_index].primary; |
@@ -588,8 +591,8 @@ static int tipc_bcbearer_send(struct sk_buff *buf, | |||
588 | if (!p) | 591 | if (!p) |
589 | break; /* no more bearers to try */ | 592 | break; /* no more bearers to try */ |
590 | 593 | ||
591 | tipc_nmap_diff(remains, &p->nodes, remains_new); | 594 | tipc_nmap_diff(&bcbearer->remains, &p->nodes, &bcbearer->remains_new); |
592 | if (remains_new->count == remains->count) | 595 | if (bcbearer->remains_new.count == bcbearer->remains.count) |
593 | continue; /* bearer pair doesn't add anything */ | 596 | continue; /* bearer pair doesn't add anything */ |
594 | 597 | ||
595 | if (!p->publ.blocked && | 598 | if (!p->publ.blocked && |
@@ -607,27 +610,17 @@ swap: | |||
607 | bcbearer->bpairs[bp_index].primary = s; | 610 | bcbearer->bpairs[bp_index].primary = s; |
608 | bcbearer->bpairs[bp_index].secondary = p; | 611 | bcbearer->bpairs[bp_index].secondary = p; |
609 | update: | 612 | update: |
610 | if (remains_new->count == 0) { | 613 | if (bcbearer->remains_new.count == 0) |
611 | err = TIPC_OK; | 614 | return TIPC_OK; |
612 | goto out; | ||
613 | } | ||
614 | 615 | ||
615 | /* swap map */ | 616 | bcbearer->remains = bcbearer->remains_new; |
616 | remains_tmp = remains; | ||
617 | remains = remains_new; | ||
618 | remains_new = remains_tmp; | ||
619 | } | 617 | } |
620 | 618 | ||
621 | /* Unable to reach all targets */ | 619 | /* Unable to reach all targets */ |
622 | 620 | ||
623 | bcbearer->bearer.publ.blocked = 1; | 621 | bcbearer->bearer.publ.blocked = 1; |
624 | bcl->stats.bearer_congs++; | 622 | bcl->stats.bearer_congs++; |
625 | err = ~TIPC_OK; | 623 | return ~TIPC_OK; |
626 | |||
627 | out: | ||
628 | kfree(remains_new); | ||
629 | kfree(remains); | ||
630 | return err; | ||
631 | } | 624 | } |
632 | 625 | ||
633 | /** | 626 | /** |