Skip to content

Commit 687f079

Browse files
committed
Merge branch 'tipc-next'
Jon Maloy says: ==================== tipc: improve broadcast implementation The TIPC broadcast link implementation is currently complex and hard to follow. It also incurs some amount of code and structure duplication, something that can be reduced significantly with a little effort. This commit series introduces a number of improvements which address both the locking structure, the code/structure duplication issue, and the overall readbility of the code. The series consists of three main parts: 1-7: Adaptation to the new link structure, and preparation for the next step. In particular, we want the broadcast transmission link to have a life cycle that is longer than any of its potential (unicast and broadcast receive links) users. This eliminates the need to always test for the presence of this link before accessing it. 8-10: This is what is really new in this series. Commit #9 is by far the largest and most important one, because it moves most of the broadcast functionality into link.c, partially reusing the fields and functionality of the unicast link. The removal of the "node_map" infrastructure in commit #10 is also an important achievement. 11-16: Some improvements leveraging the changes made in the previous commits. The series needs commit 53387c4 ("tipc: extend broadcast link window size") and commit e535679 ("tipc: conditionally expand buffer headroom over udp tunnel") which are both present in 'net' but not yet in 'net-next', to apply cleanly. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents ba3e208 + 2af5ae3 commit 687f079

File tree

17 files changed

+1005
-1387
lines changed

17 files changed

+1005
-1387
lines changed

net/tipc/bcast.c

Lines changed: 237 additions & 751 deletions
Large diffs are not rendered by default.

net/tipc/bcast.h

Lines changed: 32 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -37,102 +37,44 @@
3737
#ifndef _TIPC_BCAST_H
3838
#define _TIPC_BCAST_H
3939

40-
#include <linux/tipc_config.h>
41-
#include "link.h"
42-
#include "node.h"
40+
#include "core.h"
4341

44-
/**
45-
* struct tipc_bcbearer_pair - a pair of bearers used by broadcast link
46-
* @primary: pointer to primary bearer
47-
* @secondary: pointer to secondary bearer
48-
*
49-
* Bearers must have same priority and same set of reachable destinations
50-
* to be paired.
51-
*/
52-
53-
struct tipc_bcbearer_pair {
54-
struct tipc_bearer *primary;
55-
struct tipc_bearer *secondary;
56-
};
57-
58-
#define BCBEARER MAX_BEARERS
59-
60-
/**
61-
* struct tipc_bcbearer - bearer used by broadcast link
62-
* @bearer: (non-standard) broadcast bearer structure
63-
* @media: (non-standard) broadcast media structure
64-
* @bpairs: array of bearer pairs
65-
* @bpairs_temp: temporary array of bearer pairs used by tipc_bcbearer_sort()
66-
* @remains: temporary node map used by tipc_bcbearer_send()
67-
* @remains_new: temporary node map used tipc_bcbearer_send()
68-
*
69-
* Note: The fields labelled "temporary" are incorporated into the bearer
70-
* to avoid consuming potentially limited stack space through the use of
71-
* large local variables within multicast routines. Concurrent access is
72-
* prevented through use of the spinlock "bclink_lock".
73-
*/
74-
struct tipc_bcbearer {
75-
struct tipc_bearer bearer;
76-
struct tipc_media media;
77-
struct tipc_bcbearer_pair bpairs[MAX_BEARERS];
78-
struct tipc_bcbearer_pair bpairs_temp[TIPC_MAX_LINK_PRI + 1];
79-
struct tipc_node_map remains;
80-
struct tipc_node_map remains_new;
81-
};
42+
struct tipc_node;
43+
struct tipc_msg;
44+
struct tipc_nl_msg;
45+
struct tipc_node_map;
8246

83-
/**
84-
* struct tipc_bclink - link used for broadcast messages
85-
* @lock: spinlock governing access to structure
86-
* @link: (non-standard) broadcast link structure
87-
* @node: (non-standard) node structure representing b'cast link's peer node
88-
* @bcast_nodes: map of broadcast-capable nodes
89-
* @retransmit_to: node that most recently requested a retransmit
90-
*
91-
* Handles sequence numbering, fragmentation, bundling, etc.
92-
*/
93-
struct tipc_bclink {
94-
spinlock_t lock;
95-
struct tipc_link link;
96-
struct tipc_node node;
97-
struct sk_buff_head arrvq;
98-
struct sk_buff_head inputq;
99-
struct tipc_node_map bcast_nodes;
100-
struct tipc_node *retransmit_to;
101-
};
47+
int tipc_bcast_init(struct net *net);
48+
void tipc_bcast_reinit(struct net *net);
49+
void tipc_bcast_stop(struct net *net);
50+
void tipc_bcast_add_peer(struct net *net, struct tipc_link *l,
51+
struct sk_buff_head *xmitq);
52+
void tipc_bcast_remove_peer(struct net *net, struct tipc_link *rcv_bcl);
53+
void tipc_bcast_inc_bearer_dst_cnt(struct net *net, int bearer_id);
54+
void tipc_bcast_dec_bearer_dst_cnt(struct net *net, int bearer_id);
55+
int tipc_bcast_get_mtu(struct net *net);
56+
int tipc_bcast_xmit(struct net *net, struct sk_buff_head *list);
57+
int tipc_bcast_rcv(struct net *net, struct tipc_link *l, struct sk_buff *skb);
58+
void tipc_bcast_ack_rcv(struct net *net, struct tipc_link *l, u32 acked);
59+
void tipc_bcast_sync_rcv(struct net *net, struct tipc_link *l,
60+
struct tipc_msg *hdr);
61+
int tipc_nl_add_bc_link(struct net *net, struct tipc_nl_msg *msg);
62+
int tipc_nl_bc_link_set(struct net *net, struct nlattr *attrs[]);
63+
int tipc_bclink_reset_stats(struct net *net);
10264

103-
struct tipc_node;
104-
extern const char tipc_bclink_name[];
65+
static inline void tipc_bcast_lock(struct net *net)
66+
{
67+
spin_lock_bh(&tipc_net(net)->bclock);
68+
}
10569

106-
/**
107-
* tipc_nmap_equal - test for equality of node maps
108-
*/
109-
static inline int tipc_nmap_equal(struct tipc_node_map *nm_a,
110-
struct tipc_node_map *nm_b)
70+
static inline void tipc_bcast_unlock(struct net *net)
11171
{
112-
return !memcmp(nm_a, nm_b, sizeof(*nm_a));
72+
spin_unlock_bh(&tipc_net(net)->bclock);
11373
}
11474

115-
int tipc_bclink_init(struct net *net);
116-
void tipc_bclink_stop(struct net *net);
117-
void tipc_bclink_add_node(struct net *net, u32 addr);
118-
void tipc_bclink_remove_node(struct net *net, u32 addr);
119-
struct tipc_node *tipc_bclink_retransmit_to(struct net *tn);
120-
void tipc_bclink_acknowledge(struct tipc_node *n_ptr, u32 acked);
121-
void tipc_bclink_rcv(struct net *net, struct sk_buff *buf);
122-
u32 tipc_bclink_get_last_sent(struct net *net);
123-
u32 tipc_bclink_acks_missing(struct tipc_node *n_ptr);
124-
void tipc_bclink_update_link_state(struct tipc_node *node,
125-
u32 last_sent);
126-
int tipc_bclink_reset_stats(struct net *net);
127-
int tipc_bclink_set_queue_limits(struct net *net, u32 limit);
128-
void tipc_bcbearer_sort(struct net *net, struct tipc_node_map *nm_ptr,
129-
u32 node, bool action);
130-
uint tipc_bclink_get_mtu(void);
131-
int tipc_bclink_xmit(struct net *net, struct sk_buff_head *list);
132-
void tipc_bclink_wakeup_users(struct net *net);
133-
int tipc_nl_add_bc_link(struct net *net, struct tipc_nl_msg *msg);
134-
int tipc_nl_bc_link_set(struct net *net, struct nlattr *attrs[]);
135-
void tipc_bclink_input(struct net *net);
136-
void tipc_bclink_sync_state(struct tipc_node *n, struct tipc_msg *msg);
75+
static inline struct tipc_link *tipc_bc_sndlink(struct net *net)
76+
{
77+
return tipc_net(net)->bcl;
78+
}
13779

13880
#endif

net/tipc/bearer.c

Lines changed: 59 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -193,10 +193,8 @@ void tipc_bearer_add_dest(struct net *net, u32 bearer_id, u32 dest)
193193

194194
rcu_read_lock();
195195
b_ptr = rcu_dereference_rtnl(tn->bearer_list[bearer_id]);
196-
if (b_ptr) {
197-
tipc_bcbearer_sort(net, &b_ptr->nodes, dest, true);
196+
if (b_ptr)
198197
tipc_disc_add_dest(b_ptr->link_req);
199-
}
200198
rcu_read_unlock();
201199
}
202200

@@ -207,10 +205,8 @@ void tipc_bearer_remove_dest(struct net *net, u32 bearer_id, u32 dest)
207205

208206
rcu_read_lock();
209207
b_ptr = rcu_dereference_rtnl(tn->bearer_list[bearer_id]);
210-
if (b_ptr) {
211-
tipc_bcbearer_sort(net, &b_ptr->nodes, dest, false);
208+
if (b_ptr)
212209
tipc_disc_remove_dest(b_ptr->link_req);
213-
}
214210
rcu_read_unlock();
215211
}
216212

@@ -418,53 +414,58 @@ void tipc_disable_l2_media(struct tipc_bearer *b)
418414
* @b_ptr: the bearer through which the packet is to be sent
419415
* @dest: peer destination address
420416
*/
421-
int tipc_l2_send_msg(struct net *net, struct sk_buff *buf,
417+
int tipc_l2_send_msg(struct net *net, struct sk_buff *skb,
422418
struct tipc_bearer *b, struct tipc_media_addr *dest)
423419
{
424-
struct sk_buff *clone;
425420
struct net_device *dev;
426421
int delta;
427422

428423
dev = (struct net_device *)rcu_dereference_rtnl(b->media_ptr);
429424
if (!dev)
430425
return 0;
431426

432-
clone = skb_clone(buf, GFP_ATOMIC);
433-
if (!clone)
434-
return 0;
435-
436-
delta = dev->hard_header_len - skb_headroom(buf);
427+
delta = dev->hard_header_len - skb_headroom(skb);
437428
if ((delta > 0) &&
438-
pskb_expand_head(clone, SKB_DATA_ALIGN(delta), 0, GFP_ATOMIC)) {
439-
kfree_skb(clone);
429+
pskb_expand_head(skb, SKB_DATA_ALIGN(delta), 0, GFP_ATOMIC)) {
430+
kfree_skb(skb);
440431
return 0;
441432
}
442433

443-
skb_reset_network_header(clone);
444-
clone->dev = dev;
445-
clone->protocol = htons(ETH_P_TIPC);
446-
dev_hard_header(clone, dev, ETH_P_TIPC, dest->value,
447-
dev->dev_addr, clone->len);
448-
dev_queue_xmit(clone);
434+
skb_reset_network_header(skb);
435+
skb->dev = dev;
436+
skb->protocol = htons(ETH_P_TIPC);
437+
dev_hard_header(skb, dev, ETH_P_TIPC, dest->value,
438+
dev->dev_addr, skb->len);
439+
dev_queue_xmit(skb);
449440
return 0;
450441
}
451442

452-
/* tipc_bearer_send- sends buffer to destination over bearer
453-
*
454-
* IMPORTANT:
455-
* The media send routine must not alter the buffer being passed in
456-
* as it may be needed for later retransmission!
443+
int tipc_bearer_mtu(struct net *net, u32 bearer_id)
444+
{
445+
int mtu = 0;
446+
struct tipc_bearer *b;
447+
448+
rcu_read_lock();
449+
b = rcu_dereference_rtnl(tipc_net(net)->bearer_list[bearer_id]);
450+
if (b)
451+
mtu = b->mtu;
452+
rcu_read_unlock();
453+
return mtu;
454+
}
455+
456+
/* tipc_bearer_xmit_skb - sends buffer to destination over bearer
457457
*/
458-
void tipc_bearer_send(struct net *net, u32 bearer_id, struct sk_buff *buf,
459-
struct tipc_media_addr *dest)
458+
void tipc_bearer_xmit_skb(struct net *net, u32 bearer_id,
459+
struct sk_buff *skb,
460+
struct tipc_media_addr *dest)
460461
{
461-
struct tipc_net *tn = net_generic(net, tipc_net_id);
462-
struct tipc_bearer *b_ptr;
462+
struct tipc_net *tn = tipc_net(net);
463+
struct tipc_bearer *b;
463464

464465
rcu_read_lock();
465-
b_ptr = rcu_dereference_rtnl(tn->bearer_list[bearer_id]);
466-
if (likely(b_ptr))
467-
b_ptr->media->send_msg(net, buf, b_ptr, dest);
466+
b = rcu_dereference_rtnl(tn->bearer_list[bearer_id]);
467+
if (likely(b))
468+
b->media->send_msg(net, skb, b, dest);
468469
rcu_read_unlock();
469470
}
470471

@@ -487,8 +488,31 @@ void tipc_bearer_xmit(struct net *net, u32 bearer_id,
487488
skb_queue_walk_safe(xmitq, skb, tmp) {
488489
__skb_dequeue(xmitq);
489490
b->media->send_msg(net, skb, b, dst);
490-
/* Until we remove cloning in tipc_l2_send_msg(): */
491-
kfree_skb(skb);
491+
}
492+
}
493+
rcu_read_unlock();
494+
}
495+
496+
/* tipc_bearer_bc_xmit() - broadcast buffers to all destinations
497+
*/
498+
void tipc_bearer_bc_xmit(struct net *net, u32 bearer_id,
499+
struct sk_buff_head *xmitq)
500+
{
501+
struct tipc_net *tn = tipc_net(net);
502+
int net_id = tn->net_id;
503+
struct tipc_bearer *b;
504+
struct sk_buff *skb, *tmp;
505+
struct tipc_msg *hdr;
506+
507+
rcu_read_lock();
508+
b = rcu_dereference_rtnl(tn->bearer_list[bearer_id]);
509+
if (likely(b)) {
510+
skb_queue_walk_safe(xmitq, skb, tmp) {
511+
hdr = buf_msg(skb);
512+
msg_set_non_seq(hdr, 1);
513+
msg_set_mc_netid(hdr, net_id);
514+
__skb_dequeue(xmitq);
515+
b->media->send_msg(net, skb, b, &b->bcast_addr);
492516
}
493517
}
494518
rcu_read_unlock();

net/tipc/bearer.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ struct tipc_bearer {
163163
u32 identity;
164164
struct tipc_link_req *link_req;
165165
char net_plane;
166+
int node_cnt;
166167
struct tipc_node_map nodes;
167168
};
168169

@@ -215,10 +216,14 @@ struct tipc_media *tipc_media_find(const char *name);
215216
int tipc_bearer_setup(void);
216217
void tipc_bearer_cleanup(void);
217218
void tipc_bearer_stop(struct net *net);
218-
void tipc_bearer_send(struct net *net, u32 bearer_id, struct sk_buff *buf,
219-
struct tipc_media_addr *dest);
219+
int tipc_bearer_mtu(struct net *net, u32 bearer_id);
220+
void tipc_bearer_xmit_skb(struct net *net, u32 bearer_id,
221+
struct sk_buff *skb,
222+
struct tipc_media_addr *dest);
220223
void tipc_bearer_xmit(struct net *net, u32 bearer_id,
221224
struct sk_buff_head *xmitq,
222225
struct tipc_media_addr *dst);
226+
void tipc_bearer_bc_xmit(struct net *net, u32 bearer_id,
227+
struct sk_buff_head *xmitq);
223228

224229
#endif /* _TIPC_BEARER_H */

net/tipc/core.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
#include "bearer.h"
4343
#include "net.h"
4444
#include "socket.h"
45+
#include "bcast.h"
4546

4647
#include <linux/module.h>
4748

@@ -71,8 +72,15 @@ static int __net_init tipc_init_net(struct net *net)
7172
err = tipc_topsrv_start(net);
7273
if (err)
7374
goto out_subscr;
75+
76+
err = tipc_bcast_init(net);
77+
if (err)
78+
goto out_bclink;
79+
7480
return 0;
7581

82+
out_bclink:
83+
tipc_bcast_stop(net);
7684
out_subscr:
7785
tipc_nametbl_stop(net);
7886
out_nametbl:
@@ -85,6 +93,7 @@ static void __net_exit tipc_exit_net(struct net *net)
8593
{
8694
tipc_topsrv_stop(net);
8795
tipc_net_stop(net);
96+
tipc_bcast_stop(net);
8897
tipc_nametbl_stop(net);
8998
tipc_sk_rht_destroy(net);
9099
}

net/tipc/core.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,7 @@
6262

6363
struct tipc_node;
6464
struct tipc_bearer;
65-
struct tipc_bcbearer;
66-
struct tipc_bclink;
65+
struct tipc_bc_base;
6766
struct tipc_link;
6867
struct tipc_name_table;
6968
struct tipc_server;
@@ -93,8 +92,8 @@ struct tipc_net {
9392
struct tipc_bearer __rcu *bearer_list[MAX_BEARERS + 1];
9493

9594
/* Broadcast link */
96-
struct tipc_bcbearer *bcbearer;
97-
struct tipc_bclink *bclink;
95+
spinlock_t bclock;
96+
struct tipc_bc_base *bcbase;
9897
struct tipc_link *bcl;
9998

10099
/* Socket hash table */
@@ -114,6 +113,11 @@ static inline struct tipc_net *tipc_net(struct net *net)
114113
return net_generic(net, tipc_net_id);
115114
}
116115

116+
static inline int tipc_netid(struct net *net)
117+
{
118+
return tipc_net(net)->net_id;
119+
}
120+
117121
static inline u16 mod(u16 x)
118122
{
119123
return x & 0xffffu;

0 commit comments

Comments
 (0)