aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/bcast.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc/bcast.c')
-rw-r--r--net/tipc/bcast.c62
1 files changed, 56 insertions, 6 deletions
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
index 672e6ef93cab..7d99029df342 100644
--- a/net/tipc/bcast.c
+++ b/net/tipc/bcast.c
@@ -54,6 +54,9 @@ const char tipc_bclink_name[] = "broadcast-link";
54 * @dest: array keeping number of reachable destinations per bearer 54 * @dest: array keeping number of reachable destinations per bearer
55 * @primary_bearer: a bearer having links to all broadcast destinations, if any 55 * @primary_bearer: a bearer having links to all broadcast destinations, if any
56 * @bcast_support: indicates if primary bearer, if any, supports broadcast 56 * @bcast_support: indicates if primary bearer, if any, supports broadcast
57 * @rcast_support: indicates if all peer nodes support replicast
58 * @rc_ratio: dest count as percentage of cluster size where send method changes
59 * @bc_threshold: calculated drom rc_ratio; if dests > threshold use broadcast
57 */ 60 */
58struct tipc_bc_base { 61struct tipc_bc_base {
59 struct tipc_link *link; 62 struct tipc_link *link;
@@ -61,6 +64,9 @@ struct tipc_bc_base {
61 int dests[MAX_BEARERS]; 64 int dests[MAX_BEARERS];
62 int primary_bearer; 65 int primary_bearer;
63 bool bcast_support; 66 bool bcast_support;
67 bool rcast_support;
68 int rc_ratio;
69 int bc_threshold;
64}; 70};
65 71
66static struct tipc_bc_base *tipc_bc_base(struct net *net) 72static struct tipc_bc_base *tipc_bc_base(struct net *net)
@@ -73,6 +79,19 @@ int tipc_bcast_get_mtu(struct net *net)
73 return tipc_link_mtu(tipc_bc_sndlink(net)) - INT_H_SIZE; 79 return tipc_link_mtu(tipc_bc_sndlink(net)) - INT_H_SIZE;
74} 80}
75 81
82void tipc_bcast_disable_rcast(struct net *net)
83{
84 tipc_bc_base(net)->rcast_support = false;
85}
86
87static void tipc_bcbase_calc_bc_threshold(struct net *net)
88{
89 struct tipc_bc_base *bb = tipc_bc_base(net);
90 int cluster_size = tipc_link_bc_peers(tipc_bc_sndlink(net));
91
92 bb->bc_threshold = 1 + (cluster_size * bb->rc_ratio / 100);
93}
94
76/* tipc_bcbase_select_primary(): find a bearer with links to all destinations, 95/* tipc_bcbase_select_primary(): find a bearer with links to all destinations,
77 * if any, and make it primary bearer 96 * if any, and make it primary bearer
78 */ 97 */
@@ -175,6 +194,31 @@ static void tipc_bcbase_xmit(struct net *net, struct sk_buff_head *xmitq)
175 __skb_queue_purge(&_xmitq); 194 __skb_queue_purge(&_xmitq);
176} 195}
177 196
197static void tipc_bcast_select_xmit_method(struct net *net, int dests,
198 struct tipc_mc_method *method)
199{
200 struct tipc_bc_base *bb = tipc_bc_base(net);
201 unsigned long exp = method->expires;
202
203 /* Broadcast supported by used bearer/bearers? */
204 if (!bb->bcast_support) {
205 method->rcast = true;
206 return;
207 }
208 /* Any destinations which don't support replicast ? */
209 if (!bb->rcast_support) {
210 method->rcast = false;
211 return;
212 }
213 /* Can current method be changed ? */
214 method->expires = jiffies + TIPC_METHOD_EXPIRE;
215 if (method->mandatory || time_before(jiffies, exp))
216 return;
217
218 /* Determine method to use now */
219 method->rcast = dests <= bb->bc_threshold;
220}
221
178/* tipc_bcast_xmit - broadcast the buffer chain to all external nodes 222/* tipc_bcast_xmit - broadcast the buffer chain to all external nodes
179 * @net: the applicable net namespace 223 * @net: the applicable net namespace
180 * @pkts: chain of buffers containing message 224 * @pkts: chain of buffers containing message
@@ -237,16 +281,16 @@ static int tipc_rcast_xmit(struct net *net, struct sk_buff_head *pkts,
237 * and to identified node local sockets 281 * and to identified node local sockets
238 * @net: the applicable net namespace 282 * @net: the applicable net namespace
239 * @pkts: chain of buffers containing message 283 * @pkts: chain of buffers containing message
240 * @dests: destination nodes for message. Not consumed. 284 * @method: send method to be used
285 * @dests: destination nodes for message.
241 * @cong_link_cnt: returns number of encountered congested destination links 286 * @cong_link_cnt: returns number of encountered congested destination links
242 * @cong_links: returns identities of congested links
243 * Consumes buffer chain. 287 * Consumes buffer chain.
244 * Returns 0 if success, otherwise errno 288 * Returns 0 if success, otherwise errno
245 */ 289 */
246int tipc_mcast_xmit(struct net *net, struct sk_buff_head *pkts, 290int tipc_mcast_xmit(struct net *net, struct sk_buff_head *pkts,
247 struct tipc_nlist *dests, u16 *cong_link_cnt) 291 struct tipc_mc_method *method, struct tipc_nlist *dests,
292 u16 *cong_link_cnt)
248{ 293{
249 struct tipc_bc_base *bb = tipc_bc_base(net);
250 struct sk_buff_head inputq, localq; 294 struct sk_buff_head inputq, localq;
251 int rc = 0; 295 int rc = 0;
252 296
@@ -258,9 +302,10 @@ int tipc_mcast_xmit(struct net *net, struct sk_buff_head *pkts,
258 rc = -ENOMEM; 302 rc = -ENOMEM;
259 goto exit; 303 goto exit;
260 } 304 }
261 305 /* Send according to determined transmit method */
262 if (dests->remote) { 306 if (dests->remote) {
263 if (!bb->bcast_support) 307 tipc_bcast_select_xmit_method(net, dests->remote, method);
308 if (method->rcast)
264 rc = tipc_rcast_xmit(net, pkts, dests, cong_link_cnt); 309 rc = tipc_rcast_xmit(net, pkts, dests, cong_link_cnt);
265 else 310 else
266 rc = tipc_bcast_xmit(net, pkts, cong_link_cnt); 311 rc = tipc_bcast_xmit(net, pkts, cong_link_cnt);
@@ -269,6 +314,7 @@ int tipc_mcast_xmit(struct net *net, struct sk_buff_head *pkts,
269 if (dests->local) 314 if (dests->local)
270 tipc_sk_mcast_rcv(net, &localq, &inputq); 315 tipc_sk_mcast_rcv(net, &localq, &inputq);
271exit: 316exit:
317 /* This queue should normally be empty by now */
272 __skb_queue_purge(pkts); 318 __skb_queue_purge(pkts);
273 return rc; 319 return rc;
274} 320}
@@ -377,6 +423,7 @@ void tipc_bcast_add_peer(struct net *net, struct tipc_link *uc_l,
377 tipc_bcast_lock(net); 423 tipc_bcast_lock(net);
378 tipc_link_add_bc_peer(snd_l, uc_l, xmitq); 424 tipc_link_add_bc_peer(snd_l, uc_l, xmitq);
379 tipc_bcbase_select_primary(net); 425 tipc_bcbase_select_primary(net);
426 tipc_bcbase_calc_bc_threshold(net);
380 tipc_bcast_unlock(net); 427 tipc_bcast_unlock(net);
381} 428}
382 429
@@ -395,6 +442,7 @@ void tipc_bcast_remove_peer(struct net *net, struct tipc_link *rcv_l)
395 tipc_bcast_lock(net); 442 tipc_bcast_lock(net);
396 tipc_link_remove_bc_peer(snd_l, rcv_l, &xmitq); 443 tipc_link_remove_bc_peer(snd_l, rcv_l, &xmitq);
397 tipc_bcbase_select_primary(net); 444 tipc_bcbase_select_primary(net);
445 tipc_bcbase_calc_bc_threshold(net);
398 tipc_bcast_unlock(net); 446 tipc_bcast_unlock(net);
399 447
400 tipc_bcbase_xmit(net, &xmitq); 448 tipc_bcbase_xmit(net, &xmitq);
@@ -477,6 +525,8 @@ int tipc_bcast_init(struct net *net)
477 goto enomem; 525 goto enomem;
478 bb->link = l; 526 bb->link = l;
479 tn->bcl = l; 527 tn->bcl = l;
528 bb->rc_ratio = 25;
529 bb->rcast_support = true;
480 return 0; 530 return 0;
481enomem: 531enomem:
482 kfree(bb); 532 kfree(bb);