From d4f5d2e4b0c77f6a853204a2159a8abcf34ce6ca Mon Sep 17 00:00:00 2001 From: Allan Stephens Date: Tue, 31 May 2011 13:38:02 -0400 Subject: [PATCH] --- yaml --- r: 266119 b: refs/heads/master c: 9aa88c2a509e11e6efc466c88b386e0e01bef731 h: refs/heads/master i: 266117: b2a446336bf514ded162bcdc1a319c74ca66499e 266115: e421575c9ede68e1e8287efa32955c0273a545b3 266111: a76b342847cf316ec0334607d603fb805f212792 v: v3 --- [refs] | 2 +- trunk/net/tipc/link.c | 45 +++++++++++++++++++++++++++++++++++++ trunk/net/tipc/link.h | 1 + trunk/net/tipc/name_distr.c | 10 +++++++-- 4 files changed, 55 insertions(+), 3 deletions(-) diff --git a/[refs] b/[refs] index 7e53a5478757..b6d823700ab7 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 1c553bb52eb4c58333a843c0a5888d2329909f62 +refs/heads/master: 9aa88c2a509e11e6efc466c88b386e0e01bef731 diff --git a/trunk/net/tipc/link.c b/trunk/net/tipc/link.c index 74126db45972..2ea3f22b7986 100644 --- a/trunk/net/tipc/link.c +++ b/trunk/net/tipc/link.c @@ -985,6 +985,51 @@ int tipc_link_send(struct sk_buff *buf, u32 dest, u32 selector) return res; } +/* + * tipc_link_send_names - send name table entries to new neighbor + * + * Send routine for bulk delivery of name table messages when contact + * with a new neighbor occurs. No link congestion checking is performed + * because name table messages *must* be delivered. The messages must be + * small enough not to require fragmentation. + * Called without any locks held. + */ + +void tipc_link_send_names(struct list_head *message_list, u32 dest) +{ + struct tipc_node *n_ptr; + struct link *l_ptr; + struct sk_buff *buf; + struct sk_buff *temp_buf; + + if (list_empty(message_list)) + return; + + read_lock_bh(&tipc_net_lock); + n_ptr = tipc_node_find(dest); + if (n_ptr) { + tipc_node_lock(n_ptr); + l_ptr = n_ptr->active_links[0]; + if (l_ptr) { + /* convert circular list to linear list */ + ((struct sk_buff *)message_list->prev)->next = NULL; + link_add_chain_to_outqueue(l_ptr, + (struct sk_buff *)message_list->next, 0); + tipc_link_push_queue(l_ptr); + INIT_LIST_HEAD(message_list); + } + tipc_node_unlock(n_ptr); + } + read_unlock_bh(&tipc_net_lock); + + /* discard the messages if they couldn't be sent */ + + list_for_each_safe(buf, temp_buf, ((struct sk_buff *)message_list)) { + list_del((struct list_head *)buf); + buf_discard(buf); + } +} + /* * link_send_buf_fast: Entry for data messages where the * destination link is known and the header is complete, diff --git a/trunk/net/tipc/link.h b/trunk/net/tipc/link.h index 74fbecab1ea0..e56cb532913e 100644 --- a/trunk/net/tipc/link.h +++ b/trunk/net/tipc/link.h @@ -223,6 +223,7 @@ struct sk_buff *tipc_link_cmd_show_stats(const void *req_tlv_area, int req_tlv_s struct sk_buff *tipc_link_cmd_reset_stats(const void *req_tlv_area, int req_tlv_space); void tipc_link_reset(struct link *l_ptr); int tipc_link_send(struct sk_buff *buf, u32 dest, u32 selector); +void tipc_link_send_names(struct list_head *message_list, u32 dest); int tipc_link_send_buf(struct link *l_ptr, struct sk_buff *buf); u32 tipc_link_get_max_pkt(u32 dest, u32 selector); int tipc_link_send_sections_fast(struct tipc_port *sender, diff --git a/trunk/net/tipc/name_distr.c b/trunk/net/tipc/name_distr.c index 97546f07938c..b7ca1bd7b151 100644 --- a/trunk/net/tipc/name_distr.c +++ b/trunk/net/tipc/name_distr.c @@ -180,6 +180,7 @@ void tipc_named_node_up(unsigned long nodearg) struct publication *publ; struct distr_item *item = NULL; struct sk_buff *buf = NULL; + struct list_head message_list; u32 node = (u32)nodearg; u32 left = 0; u32 rest; @@ -201,6 +202,10 @@ void tipc_named_node_up(unsigned long nodearg) if (!max_item_buf) return; + /* create list of publication messages, then send them as a unit */ + + INIT_LIST_HEAD(&message_list); + read_lock_bh(&tipc_nametbl_lock); rest = publ_cnt * ITEM_SIZE; @@ -219,13 +224,14 @@ void tipc_named_node_up(unsigned long nodearg) item++; left -= ITEM_SIZE; if (!left) { - msg_set_link_selector(buf_msg(buf), node); - tipc_link_send(buf, node, node); + list_add_tail((struct list_head *)buf, &message_list); buf = NULL; } } exit: read_unlock_bh(&tipc_nametbl_lock); + + tipc_link_send_names(&message_list, (u32)node); } /**