diff options
Diffstat (limited to 'net/tipc')
-rw-r--r-- | net/tipc/link.c | 41 | ||||
-rw-r--r-- | net/tipc/link.h | 1 | ||||
-rw-r--r-- | net/tipc/name_distr.c | 76 | ||||
-rw-r--r-- | net/tipc/name_distr.h | 2 | ||||
-rw-r--r-- | net/tipc/node.c | 13 |
5 files changed, 48 insertions, 85 deletions
diff --git a/net/tipc/link.c b/net/tipc/link.c index a235b245f682..367b0f5886f8 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c | |||
@@ -1033,47 +1033,6 @@ static void tipc_link_sync_rcv(struct tipc_node *n, struct sk_buff *buf) | |||
1033 | } | 1033 | } |
1034 | 1034 | ||
1035 | /* | 1035 | /* |
1036 | * tipc_link_names_xmit - send name table entries to new neighbor | ||
1037 | * | ||
1038 | * Send routine for bulk delivery of name table messages when contact | ||
1039 | * with a new neighbor occurs. No link congestion checking is performed | ||
1040 | * because name table messages *must* be delivered. The messages must be | ||
1041 | * small enough not to require fragmentation. | ||
1042 | * Called without any locks held. | ||
1043 | */ | ||
1044 | void tipc_link_names_xmit(struct list_head *message_list, u32 dest) | ||
1045 | { | ||
1046 | struct tipc_node *n_ptr; | ||
1047 | struct tipc_link *l_ptr; | ||
1048 | struct sk_buff *buf; | ||
1049 | struct sk_buff *temp_buf; | ||
1050 | |||
1051 | if (list_empty(message_list)) | ||
1052 | return; | ||
1053 | |||
1054 | n_ptr = tipc_node_find(dest); | ||
1055 | if (n_ptr) { | ||
1056 | tipc_node_lock(n_ptr); | ||
1057 | l_ptr = n_ptr->active_links[0]; | ||
1058 | if (l_ptr) { | ||
1059 | /* convert circular list to linear list */ | ||
1060 | ((struct sk_buff *)message_list->prev)->next = NULL; | ||
1061 | link_add_chain_to_outqueue(l_ptr, | ||
1062 | (struct sk_buff *)message_list->next, 0); | ||
1063 | tipc_link_push_queue(l_ptr); | ||
1064 | INIT_LIST_HEAD(message_list); | ||
1065 | } | ||
1066 | tipc_node_unlock(n_ptr); | ||
1067 | } | ||
1068 | |||
1069 | /* discard the messages if they couldn't be sent */ | ||
1070 | list_for_each_safe(buf, temp_buf, ((struct sk_buff *)message_list)) { | ||
1071 | list_del((struct list_head *)buf); | ||
1072 | kfree_skb(buf); | ||
1073 | } | ||
1074 | } | ||
1075 | |||
1076 | /* | ||
1077 | * tipc_link_push_packet: Push one unsent packet to the media | 1036 | * tipc_link_push_packet: Push one unsent packet to the media |
1078 | */ | 1037 | */ |
1079 | static u32 tipc_link_push_packet(struct tipc_link *l_ptr) | 1038 | static u32 tipc_link_push_packet(struct tipc_link *l_ptr) |
diff --git a/net/tipc/link.h b/net/tipc/link.h index 227ff8120897..04a59c58d385 100644 --- a/net/tipc/link.h +++ b/net/tipc/link.h | |||
@@ -228,7 +228,6 @@ void tipc_link_reset(struct tipc_link *l_ptr); | |||
228 | void tipc_link_reset_list(unsigned int bearer_id); | 228 | void tipc_link_reset_list(unsigned int bearer_id); |
229 | int tipc_link_xmit(struct sk_buff *buf, u32 dest, u32 selector); | 229 | int tipc_link_xmit(struct sk_buff *buf, u32 dest, u32 selector); |
230 | int tipc_link_xmit2(struct sk_buff *buf, u32 dest, u32 selector); | 230 | int tipc_link_xmit2(struct sk_buff *buf, u32 dest, u32 selector); |
231 | void tipc_link_names_xmit(struct list_head *message_list, u32 dest); | ||
232 | int __tipc_link_xmit(struct tipc_link *l_ptr, struct sk_buff *buf); | 231 | int __tipc_link_xmit(struct tipc_link *l_ptr, struct sk_buff *buf); |
233 | int __tipc_link_xmit2(struct tipc_link *link, struct sk_buff *buf); | 232 | int __tipc_link_xmit2(struct tipc_link *link, struct sk_buff *buf); |
234 | int tipc_link_send_buf(struct tipc_link *l_ptr, struct sk_buff *buf); | 233 | int tipc_link_send_buf(struct tipc_link *l_ptr, struct sk_buff *buf); |
diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c index 8ce730984aa1..d16f9475fa76 100644 --- a/net/tipc/name_distr.c +++ b/net/tipc/name_distr.c | |||
@@ -101,24 +101,22 @@ static struct sk_buff *named_prepare_buf(u32 type, u32 size, u32 dest) | |||
101 | 101 | ||
102 | void named_cluster_distribute(struct sk_buff *buf) | 102 | void named_cluster_distribute(struct sk_buff *buf) |
103 | { | 103 | { |
104 | struct sk_buff *buf_copy; | 104 | struct sk_buff *obuf; |
105 | struct tipc_node *n_ptr; | 105 | struct tipc_node *node; |
106 | struct tipc_link *l_ptr; | 106 | u32 dnode; |
107 | 107 | ||
108 | rcu_read_lock(); | 108 | rcu_read_lock(); |
109 | list_for_each_entry_rcu(n_ptr, &tipc_node_list, list) { | 109 | list_for_each_entry_rcu(node, &tipc_node_list, list) { |
110 | tipc_node_lock(n_ptr); | 110 | dnode = node->addr; |
111 | l_ptr = n_ptr->active_links[n_ptr->addr & 1]; | 111 | if (in_own_node(dnode)) |
112 | if (l_ptr) { | 112 | continue; |
113 | buf_copy = skb_copy(buf, GFP_ATOMIC); | 113 | if (!tipc_node_active_links(node)) |
114 | if (!buf_copy) { | 114 | continue; |
115 | tipc_node_unlock(n_ptr); | 115 | obuf = skb_copy(buf, GFP_ATOMIC); |
116 | break; | 116 | if (!obuf) |
117 | } | 117 | break; |
118 | msg_set_destnode(buf_msg(buf_copy), n_ptr->addr); | 118 | msg_set_destnode(buf_msg(obuf), dnode); |
119 | __tipc_link_xmit(l_ptr, buf_copy); | 119 | tipc_link_xmit2(obuf, dnode, dnode); |
120 | } | ||
121 | tipc_node_unlock(n_ptr); | ||
122 | } | 120 | } |
123 | rcu_read_unlock(); | 121 | rcu_read_unlock(); |
124 | 122 | ||
@@ -175,34 +173,44 @@ struct sk_buff *tipc_named_withdraw(struct publication *publ) | |||
175 | return buf; | 173 | return buf; |
176 | } | 174 | } |
177 | 175 | ||
178 | /* | 176 | /** |
179 | * named_distribute - prepare name info for bulk distribution to another node | 177 | * named_distribute - prepare name info for bulk distribution to another node |
178 | * @msg_list: list of messages (buffers) to be returned from this function | ||
179 | * @dnode: node to be updated | ||
180 | * @pls: linked list of publication items to be packed into buffer chain | ||
180 | */ | 181 | */ |
181 | static void named_distribute(struct list_head *message_list, u32 node, | 182 | static void named_distribute(struct list_head *msg_list, u32 dnode, |
182 | struct publ_list *pls, u32 max_item_buf) | 183 | struct publ_list *pls) |
183 | { | 184 | { |
184 | struct publication *publ; | 185 | struct publication *publ; |
185 | struct sk_buff *buf = NULL; | 186 | struct sk_buff *buf = NULL; |
186 | struct distr_item *item = NULL; | 187 | struct distr_item *item = NULL; |
187 | u32 left = 0; | 188 | uint dsz = pls->size * ITEM_SIZE; |
188 | u32 rest = pls->size * ITEM_SIZE; | 189 | uint msg_dsz = (tipc_node_get_mtu(dnode, 0) / ITEM_SIZE) * ITEM_SIZE; |
190 | uint rem = dsz; | ||
191 | uint msg_rem = 0; | ||
189 | 192 | ||
190 | list_for_each_entry(publ, &pls->list, local_list) { | 193 | list_for_each_entry(publ, &pls->list, local_list) { |
194 | /* Prepare next buffer: */ | ||
191 | if (!buf) { | 195 | if (!buf) { |
192 | left = (rest <= max_item_buf) ? rest : max_item_buf; | 196 | msg_rem = min_t(uint, rem, msg_dsz); |
193 | rest -= left; | 197 | rem -= msg_rem; |
194 | buf = named_prepare_buf(PUBLICATION, left, node); | 198 | buf = named_prepare_buf(PUBLICATION, msg_rem, dnode); |
195 | if (!buf) { | 199 | if (!buf) { |
196 | pr_warn("Bulk publication failure\n"); | 200 | pr_warn("Bulk publication failure\n"); |
197 | return; | 201 | return; |
198 | } | 202 | } |
199 | item = (struct distr_item *)msg_data(buf_msg(buf)); | 203 | item = (struct distr_item *)msg_data(buf_msg(buf)); |
200 | } | 204 | } |
205 | |||
206 | /* Pack publication into message: */ | ||
201 | publ_to_item(item, publ); | 207 | publ_to_item(item, publ); |
202 | item++; | 208 | item++; |
203 | left -= ITEM_SIZE; | 209 | msg_rem -= ITEM_SIZE; |
204 | if (!left) { | 210 | |
205 | list_add_tail((struct list_head *)buf, message_list); | 211 | /* Append full buffer to list: */ |
212 | if (!msg_rem) { | ||
213 | list_add_tail((struct list_head *)buf, msg_list); | ||
206 | buf = NULL; | 214 | buf = NULL; |
207 | } | 215 | } |
208 | } | 216 | } |
@@ -211,16 +219,20 @@ static void named_distribute(struct list_head *message_list, u32 node, | |||
211 | /** | 219 | /** |
212 | * tipc_named_node_up - tell specified node about all publications by this node | 220 | * tipc_named_node_up - tell specified node about all publications by this node |
213 | */ | 221 | */ |
214 | void tipc_named_node_up(u32 max_item_buf, u32 node) | 222 | void tipc_named_node_up(u32 dnode) |
215 | { | 223 | { |
216 | LIST_HEAD(message_list); | 224 | LIST_HEAD(msg_list); |
225 | struct sk_buff *buf_chain; | ||
217 | 226 | ||
218 | read_lock_bh(&tipc_nametbl_lock); | 227 | read_lock_bh(&tipc_nametbl_lock); |
219 | named_distribute(&message_list, node, &publ_cluster, max_item_buf); | 228 | named_distribute(&msg_list, dnode, &publ_cluster); |
220 | named_distribute(&message_list, node, &publ_zone, max_item_buf); | 229 | named_distribute(&msg_list, dnode, &publ_zone); |
221 | read_unlock_bh(&tipc_nametbl_lock); | 230 | read_unlock_bh(&tipc_nametbl_lock); |
222 | 231 | ||
223 | tipc_link_names_xmit(&message_list, node); | 232 | /* Convert circular list to linear list and send: */ |
233 | buf_chain = (struct sk_buff *)msg_list.next; | ||
234 | ((struct sk_buff *)msg_list.prev)->next = NULL; | ||
235 | tipc_link_xmit2(buf_chain, dnode, dnode); | ||
224 | } | 236 | } |
225 | 237 | ||
226 | /** | 238 | /** |
diff --git a/net/tipc/name_distr.h b/net/tipc/name_distr.h index b2eed4ec1526..8afe32b7fc9a 100644 --- a/net/tipc/name_distr.h +++ b/net/tipc/name_distr.h | |||
@@ -70,7 +70,7 @@ struct distr_item { | |||
70 | struct sk_buff *tipc_named_publish(struct publication *publ); | 70 | struct sk_buff *tipc_named_publish(struct publication *publ); |
71 | struct sk_buff *tipc_named_withdraw(struct publication *publ); | 71 | struct sk_buff *tipc_named_withdraw(struct publication *publ); |
72 | void named_cluster_distribute(struct sk_buff *buf); | 72 | void named_cluster_distribute(struct sk_buff *buf); |
73 | void tipc_named_node_up(u32 max_item_buf, u32 node); | 73 | void tipc_named_node_up(u32 dnode); |
74 | void tipc_named_rcv(struct sk_buff *buf); | 74 | void tipc_named_rcv(struct sk_buff *buf); |
75 | void tipc_named_reinit(void); | 75 | void tipc_named_reinit(void); |
76 | 76 | ||
diff --git a/net/tipc/node.c b/net/tipc/node.c index d959343043fd..f7069299943f 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c | |||
@@ -474,8 +474,6 @@ int tipc_node_get_linkname(u32 bearer_id, u32 addr, char *linkname, size_t len) | |||
474 | void tipc_node_unlock(struct tipc_node *node) | 474 | void tipc_node_unlock(struct tipc_node *node) |
475 | { | 475 | { |
476 | LIST_HEAD(nsub_list); | 476 | LIST_HEAD(nsub_list); |
477 | struct tipc_link *link; | ||
478 | int pkt_sz = 0; | ||
479 | u32 addr = 0; | 477 | u32 addr = 0; |
480 | 478 | ||
481 | if (likely(!node->action_flags)) { | 479 | if (likely(!node->action_flags)) { |
@@ -488,18 +486,13 @@ void tipc_node_unlock(struct tipc_node *node) | |||
488 | node->action_flags &= ~TIPC_NOTIFY_NODE_DOWN; | 486 | node->action_flags &= ~TIPC_NOTIFY_NODE_DOWN; |
489 | } | 487 | } |
490 | if (node->action_flags & TIPC_NOTIFY_NODE_UP) { | 488 | if (node->action_flags & TIPC_NOTIFY_NODE_UP) { |
491 | link = node->active_links[0]; | ||
492 | node->action_flags &= ~TIPC_NOTIFY_NODE_UP; | 489 | node->action_flags &= ~TIPC_NOTIFY_NODE_UP; |
493 | if (link) { | 490 | addr = node->addr; |
494 | pkt_sz = ((link->max_pkt - INT_H_SIZE) / ITEM_SIZE) * | ||
495 | ITEM_SIZE; | ||
496 | addr = node->addr; | ||
497 | } | ||
498 | } | 491 | } |
499 | spin_unlock_bh(&node->lock); | 492 | spin_unlock_bh(&node->lock); |
500 | 493 | ||
501 | if (!list_empty(&nsub_list)) | 494 | if (!list_empty(&nsub_list)) |
502 | tipc_nodesub_notify(&nsub_list); | 495 | tipc_nodesub_notify(&nsub_list); |
503 | if (pkt_sz) | 496 | if (addr) |
504 | tipc_named_node_up(pkt_sz, addr); | 497 | tipc_named_node_up(addr); |
505 | } | 498 | } |