Skip to content

Commit a80ae53

Browse files
Jon Maloydavem330
authored andcommitted
tipc: improve destination linked list
We often see a need for a linked list of destination identities, sometimes containing a port number, sometimes a node identity, and sometimes both. The currently defined struct u32_list is not generic enough to cover all cases, so we extend it to contain two u32 integers and rename it to struct tipc_dest_list. Signed-off-by: Jon Maloy <[email protected]> Acked-by: Ying Xue <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent f70d37b commit a80ae53

File tree

4 files changed

+74
-67
lines changed

4 files changed

+74
-67
lines changed

net/tipc/bcast.c

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -258,20 +258,20 @@ static int tipc_bcast_xmit(struct net *net, struct sk_buff_head *pkts,
258258
static int tipc_rcast_xmit(struct net *net, struct sk_buff_head *pkts,
259259
struct tipc_nlist *dests, u16 *cong_link_cnt)
260260
{
261+
struct tipc_dest *dst, *tmp;
261262
struct sk_buff_head _pkts;
262-
struct u32_item *n, *tmp;
263-
u32 dst, selector;
263+
u32 dnode, selector;
264264

265265
selector = msg_link_selector(buf_msg(skb_peek(pkts)));
266266
skb_queue_head_init(&_pkts);
267267

268-
list_for_each_entry_safe(n, tmp, &dests->list, list) {
269-
dst = n->value;
270-
if (!tipc_msg_pskb_copy(dst, pkts, &_pkts))
268+
list_for_each_entry_safe(dst, tmp, &dests->list, list) {
269+
dnode = dst->node;
270+
if (!tipc_msg_pskb_copy(dnode, pkts, &_pkts))
271271
return -ENOMEM;
272272

273273
/* Any other return value than -ELINKCONG is ignored */
274-
if (tipc_node_xmit(net, &_pkts, dst, selector) == -ELINKCONG)
274+
if (tipc_node_xmit(net, &_pkts, dnode, selector) == -ELINKCONG)
275275
(*cong_link_cnt)++;
276276
}
277277
return 0;
@@ -554,21 +554,21 @@ void tipc_nlist_add(struct tipc_nlist *nl, u32 node)
554554
{
555555
if (node == nl->self)
556556
nl->local = true;
557-
else if (u32_push(&nl->list, node))
557+
else if (tipc_dest_push(&nl->list, node, 0))
558558
nl->remote++;
559559
}
560560

561561
void tipc_nlist_del(struct tipc_nlist *nl, u32 node)
562562
{
563563
if (node == nl->self)
564564
nl->local = false;
565-
else if (u32_del(&nl->list, node))
565+
else if (tipc_dest_del(&nl->list, node, 0))
566566
nl->remote--;
567567
}
568568

569569
void tipc_nlist_purge(struct tipc_nlist *nl)
570570
{
571-
u32_list_purge(&nl->list);
571+
tipc_dest_list_purge(&nl->list);
572572
nl->remote = 0;
573573
nl->local = 0;
574574
}

net/tipc/name_table.c

Lines changed: 45 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -634,7 +634,7 @@ int tipc_nametbl_mc_translate(struct net *net, u32 type, u32 lower, u32 upper,
634634
info = sseq->info;
635635
list_for_each_entry(publ, &info->node_list, node_list) {
636636
if (publ->scope <= limit)
637-
u32_push(dports, publ->ref);
637+
tipc_dest_push(dports, 0, publ->ref);
638638
}
639639

640640
if (info->cluster_list_size != info->node_list_size)
@@ -1057,78 +1057,79 @@ int tipc_nl_name_table_dump(struct sk_buff *skb, struct netlink_callback *cb)
10571057
return skb->len;
10581058
}
10591059

1060-
bool u32_find(struct list_head *l, u32 value)
1060+
struct tipc_dest *tipc_dest_find(struct list_head *l, u32 node, u32 port)
10611061
{
1062-
struct u32_item *item;
1062+
u64 value = (u64)node << 32 | port;
1063+
struct tipc_dest *dst;
10631064

1064-
list_for_each_entry(item, l, list) {
1065-
if (item->value == value)
1066-
return true;
1065+
list_for_each_entry(dst, l, list) {
1066+
if (dst->value != value)
1067+
continue;
1068+
return dst;
10671069
}
1068-
return false;
1070+
return NULL;
10691071
}
10701072

1071-
bool u32_push(struct list_head *l, u32 value)
1073+
bool tipc_dest_push(struct list_head *l, u32 node, u32 port)
10721074
{
1073-
struct u32_item *item;
1075+
u64 value = (u64)node << 32 | port;
1076+
struct tipc_dest *dst;
10741077

1075-
list_for_each_entry(item, l, list) {
1076-
if (item->value == value)
1077-
return false;
1078-
}
1079-
item = kmalloc(sizeof(*item), GFP_ATOMIC);
1080-
if (unlikely(!item))
1078+
if (tipc_dest_find(l, node, port))
10811079
return false;
10821080

1083-
item->value = value;
1084-
list_add(&item->list, l);
1081+
dst = kmalloc(sizeof(*dst), GFP_ATOMIC);
1082+
if (unlikely(!dst))
1083+
return false;
1084+
dst->value = value;
1085+
list_add(&dst->list, l);
10851086
return true;
10861087
}
10871088

1088-
u32 u32_pop(struct list_head *l)
1089+
bool tipc_dest_pop(struct list_head *l, u32 *node, u32 *port)
10891090
{
1090-
struct u32_item *item;
1091-
u32 value = 0;
1091+
struct tipc_dest *dst;
10921092

10931093
if (list_empty(l))
1094-
return 0;
1095-
item = list_first_entry(l, typeof(*item), list);
1096-
value = item->value;
1097-
list_del(&item->list);
1098-
kfree(item);
1099-
return value;
1094+
return false;
1095+
dst = list_first_entry(l, typeof(*dst), list);
1096+
if (port)
1097+
*port = dst->port;
1098+
if (node)
1099+
*node = dst->node;
1100+
list_del(&dst->list);
1101+
kfree(dst);
1102+
return true;
11001103
}
11011104

1102-
bool u32_del(struct list_head *l, u32 value)
1105+
bool tipc_dest_del(struct list_head *l, u32 node, u32 port)
11031106
{
1104-
struct u32_item *item, *tmp;
1107+
struct tipc_dest *dst;
11051108

1106-
list_for_each_entry_safe(item, tmp, l, list) {
1107-
if (item->value != value)
1108-
continue;
1109-
list_del(&item->list);
1110-
kfree(item);
1111-
return true;
1112-
}
1113-
return false;
1109+
dst = tipc_dest_find(l, node, port);
1110+
if (!dst)
1111+
return false;
1112+
list_del(&dst->list);
1113+
kfree(dst);
1114+
return true;
11141115
}
11151116

1116-
void u32_list_purge(struct list_head *l)
1117+
void tipc_dest_list_purge(struct list_head *l)
11171118
{
1118-
struct u32_item *item, *tmp;
1119+
struct tipc_dest *dst, *tmp;
11191120

1120-
list_for_each_entry_safe(item, tmp, l, list) {
1121-
list_del(&item->list);
1122-
kfree(item);
1121+
list_for_each_entry_safe(dst, tmp, l, list) {
1122+
list_del(&dst->list);
1123+
kfree(dst);
11231124
}
11241125
}
11251126

1126-
int u32_list_len(struct list_head *l)
1127+
int tipc_dest_list_len(struct list_head *l)
11271128
{
1128-
struct u32_item *item;
1129+
struct tipc_dest *dst;
11291130
int i = 0;
11301131

1131-
list_for_each_entry(item, l, list) {
1132+
list_for_each_entry(dst, l, list) {
11321133
i++;
11331134
}
11341135
return i;

net/tipc/name_table.h

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -120,16 +120,22 @@ void tipc_nametbl_unsubscribe(struct tipc_subscription *s);
120120
int tipc_nametbl_init(struct net *net);
121121
void tipc_nametbl_stop(struct net *net);
122122

123-
struct u32_item {
123+
struct tipc_dest {
124124
struct list_head list;
125-
u32 value;
125+
union {
126+
struct {
127+
u32 port;
128+
u32 node;
129+
};
130+
u64 value;
131+
};
126132
};
127133

128-
bool u32_push(struct list_head *l, u32 value);
129-
u32 u32_pop(struct list_head *l);
130-
bool u32_find(struct list_head *l, u32 value);
131-
bool u32_del(struct list_head *l, u32 value);
132-
void u32_list_purge(struct list_head *l);
133-
int u32_list_len(struct list_head *l);
134+
struct tipc_dest *tipc_dest_find(struct list_head *l, u32 node, u32 port);
135+
bool tipc_dest_push(struct list_head *l, u32 node, u32 port);
136+
bool tipc_dest_pop(struct list_head *l, u32 *node, u32 *port);
137+
bool tipc_dest_del(struct list_head *l, u32 node, u32 port);
138+
void tipc_dest_list_purge(struct list_head *l);
139+
int tipc_dest_list_len(struct list_head *l);
134140

135141
#endif

net/tipc/socket.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -565,7 +565,7 @@ static int tipc_release(struct socket *sock)
565565

566566
/* Reject any messages that accumulated in backlog queue */
567567
release_sock(sk);
568-
u32_list_purge(&tsk->cong_links);
568+
tipc_dest_list_purge(&tsk->cong_links);
569569
tsk->cong_link_cnt = 0;
570570
call_rcu(&tsk->rcu, tipc_sk_callback);
571571
sock->sk = NULL;
@@ -826,8 +826,7 @@ void tipc_sk_mcast_rcv(struct net *net, struct sk_buff_head *arrvq,
826826
tipc_nametbl_mc_translate(net,
827827
msg_nametype(msg), msg_namelower(msg),
828828
msg_nameupper(msg), scope, &dports);
829-
portid = u32_pop(&dports);
830-
for (; portid; portid = u32_pop(&dports)) {
829+
while (tipc_dest_pop(&dports, NULL, &portid)) {
831830
_skb = __pskb_copy(skb, hsz, GFP_ATOMIC);
832831
if (_skb) {
833832
msg_set_destport(buf_msg(_skb), portid);
@@ -1000,7 +999,8 @@ static int __tipc_sendmsg(struct socket *sock, struct msghdr *m, size_t dlen)
1000999
}
10011000

10021001
/* Block or return if destination link is congested */
1003-
rc = tipc_wait_for_cond(sock, &timeout, !u32_find(clinks, dnode));
1002+
rc = tipc_wait_for_cond(sock, &timeout,
1003+
!tipc_dest_find(clinks, dnode, 0));
10041004
if (unlikely(rc))
10051005
return rc;
10061006

@@ -1012,7 +1012,7 @@ static int __tipc_sendmsg(struct socket *sock, struct msghdr *m, size_t dlen)
10121012

10131013
rc = tipc_node_xmit(net, &pkts, dnode, tsk->portid);
10141014
if (unlikely(rc == -ELINKCONG)) {
1015-
u32_push(clinks, dnode);
1015+
tipc_dest_push(clinks, dnode, 0);
10161016
tsk->cong_link_cnt++;
10171017
rc = 0;
10181018
}
@@ -1549,7 +1549,7 @@ static void tipc_sk_proto_rcv(struct sock *sk,
15491549
tipc_sk_conn_proto_rcv(tsk, skb, xmitq);
15501550
return;
15511551
case SOCK_WAKEUP:
1552-
u32_del(&tsk->cong_links, msg_orignode(hdr));
1552+
tipc_dest_del(&tsk->cong_links, msg_orignode(hdr), 0);
15531553
tsk->cong_link_cnt--;
15541554
sk->sk_write_space(sk);
15551555
break;

0 commit comments

Comments
 (0)