|
@@ -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 {
|
|
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,
|
|
{
|
|
{
|
|
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,
|
|
|
|
|
|
/* Send buffer over bearers until all targets reached */
|
|
/* Send buffer over bearers until all targets reached */
|
|
|
|
|
|
- remains = kmalloc(sizeof(struct node_map), GFP_ATOMIC);
|
|
|
|
- remains_new = kmalloc(sizeof(struct node_map), GFP_ATOMIC);
|
|
|
|
- *remains = tipc_cltr_bcast_nodes;
|
|
|
|
|
|
+ bcbearer->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,
|
|
if (!p)
|
|
if (!p)
|
|
break; /* no more bearers to try */
|
|
break; /* no more bearers to try */
|
|
|
|
|
|
- tipc_nmap_diff(remains, &p->nodes, remains_new);
|
|
|
|
- if (remains_new->count == remains->count)
|
|
|
|
|
|
+ tipc_nmap_diff(&bcbearer->remains, &p->nodes, &bcbearer->remains_new);
|
|
|
|
+ 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 @@ swap:
|
|
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) {
|
|
|
|
- err = TIPC_OK;
|
|
|
|
- goto out;
|
|
|
|
- }
|
|
|
|
|
|
+ if (bcbearer->remains_new.count == 0)
|
|
|
|
+ return TIPC_OK;
|
|
|
|
|
|
- /* swap map */
|
|
|
|
- remains_tmp = remains;
|
|
|
|
- remains = remains_new;
|
|
|
|
- remains_new = remains_tmp;
|
|
|
|
|
|
+ bcbearer->remains = bcbearer->remains_new;
|
|
}
|
|
}
|
|
|
|
|
|
/* 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;
|
|
|
|
-
|
|
|
|
- out:
|
|
|
|
- kfree(remains_new);
|
|
|
|
- kfree(remains);
|
|
|
|
- return err;
|
|
|
|
|
|
+ return ~TIPC_OK;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|