Commit 65f51ef0 authored by Allan Stephens's avatar Allan Stephens Committed by David S. Miller

[TIPC]: Get rid of dynamically allocated arrays in broadcast code.

This change improves an earlier change which replaced the large local
variable arrays used during broadcasting with dynamically allocated arrays.
The temporary arrays are now incoprorated into the multicast link data
structure.
Signed-off-by: default avatarAllan Stephens <allan.stephens@windriver.com>
Signed-off-by: default avatarPer Liden <per.liden@ericsson.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 5392d646
...@@ -81,7 +81,14 @@ struct bcbearer_pair { ...@@ -81,7 +81,14 @@ struct bcbearer_pair {
* @bearer: (non-standard) broadcast bearer structure * @bearer: (non-standard) broadcast bearer structure
* @media: (non-standard) broadcast media structure * @media: (non-standard) broadcast media structure
* @bpairs: array of bearer pairs * @bpairs: array of bearer pairs
* @bpairs_temp: array of bearer pairs used during creation of "bpairs" * @bpairs_temp: temporary array of bearer pairs used by tipc_bcbearer_sort()
* @remains: temporary node map used by tipc_bcbearer_send()
* @remains_new: temporary node map used tipc_bcbearer_send()
*
* Note: The fields labelled "temporary" are incorporated into the bearer
* to avoid consuming potentially limited stack space through the use of
* large local variables within multicast routines. Concurrent access is
* prevented through use of the spinlock "bc_lock".
*/ */
struct bcbearer { struct bcbearer {
...@@ -89,6 +96,8 @@ struct bcbearer { ...@@ -89,6 +96,8 @@ struct bcbearer {
struct media media; struct media media;
struct bcbearer_pair bpairs[MAX_BEARERS]; struct bcbearer_pair bpairs[MAX_BEARERS];
struct bcbearer_pair bpairs_temp[TIPC_MAX_LINK_PRI + 1]; struct bcbearer_pair bpairs_temp[TIPC_MAX_LINK_PRI + 1];
struct node_map remains;
struct node_map remains_new;
}; };
/** /**
...@@ -551,12 +560,8 @@ static int tipc_bcbearer_send(struct sk_buff *buf, ...@@ -551,12 +560,8 @@ static int tipc_bcbearer_send(struct sk_buff *buf,
{ {
static int send_count = 0; static int send_count = 0;
struct node_map *remains;
struct node_map *remains_new;
struct node_map *remains_tmp;
int bp_index; int bp_index;
int swap_time; int swap_time;
int err;
/* Prepare buffer for broadcasting (if first time trying to send it) */ /* Prepare buffer for broadcasting (if first time trying to send it) */
...@@ -577,9 +582,7 @@ static int tipc_bcbearer_send(struct sk_buff *buf, ...@@ -577,9 +582,7 @@ static int tipc_bcbearer_send(struct sk_buff *buf,
/* Send buffer over bearers until all targets reached */ /* Send buffer over bearers until all targets reached */
remains = kmalloc(sizeof(struct node_map), GFP_ATOMIC); bcbearer->remains = tipc_cltr_bcast_nodes;
remains_new = kmalloc(sizeof(struct node_map), GFP_ATOMIC);
*remains = tipc_cltr_bcast_nodes;
for (bp_index = 0; bp_index < MAX_BEARERS; bp_index++) { for (bp_index = 0; bp_index < MAX_BEARERS; bp_index++) {
struct bearer *p = bcbearer->bpairs[bp_index].primary; struct bearer *p = bcbearer->bpairs[bp_index].primary;
...@@ -588,8 +591,8 @@ static int tipc_bcbearer_send(struct sk_buff *buf, ...@@ -588,8 +591,8 @@ static int tipc_bcbearer_send(struct sk_buff *buf,
if (!p) if (!p)
break; /* no more bearers to try */ break; /* no more bearers to try */
tipc_nmap_diff(remains, &p->nodes, remains_new); tipc_nmap_diff(&bcbearer->remains, &p->nodes, &bcbearer->remains_new);
if (remains_new->count == remains->count) if (bcbearer->remains_new.count == bcbearer->remains.count)
continue; /* bearer pair doesn't add anything */ continue; /* bearer pair doesn't add anything */
if (!p->publ.blocked && if (!p->publ.blocked &&
...@@ -607,27 +610,17 @@ static int tipc_bcbearer_send(struct sk_buff *buf, ...@@ -607,27 +610,17 @@ static int tipc_bcbearer_send(struct sk_buff *buf,
bcbearer->bpairs[bp_index].primary = s; bcbearer->bpairs[bp_index].primary = s;
bcbearer->bpairs[bp_index].secondary = p; bcbearer->bpairs[bp_index].secondary = p;
update: update:
if (remains_new->count == 0) { if (bcbearer->remains_new.count == 0)
err = TIPC_OK; return TIPC_OK;
goto out;
}
/* swap map */ bcbearer->remains = bcbearer->remains_new;
remains_tmp = remains;
remains = remains_new;
remains_new = remains_tmp;
} }
/* Unable to reach all targets */ /* Unable to reach all targets */
bcbearer->bearer.publ.blocked = 1; bcbearer->bearer.publ.blocked = 1;
bcl->stats.bearer_congs++; bcl->stats.bearer_congs++;
err = ~TIPC_OK; return ~TIPC_OK;
out:
kfree(remains_new);
kfree(remains);
return err;
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment