aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/node.c
diff options
context:
space:
mode:
authorJon Paul Maloy <jon.maloy@ericsson.com>2015-07-16 16:54:24 -0400
committerDavid S. Miller <davem@davemloft.net>2015-07-20 23:41:15 -0400
commitaf9b028e270fda6fb812d70d17d902297df1ceb5 (patch)
tree1a204c6d10d597d5db18908dc2066e980a78120d /net/tipc/node.c
parent22d85c79428b8ca9a01623aa3e3a1fe29a30a119 (diff)
tipc: make media xmit call outside node spinlock context
Currently, message sending is performed through a deep call chain, where the node spinlock is grabbed and held during a significant part of the transmission time. This is clearly detrimental to overall throughput performance; it would be better if we could send the message after the spinlock has been released. In this commit, we do instead let the call revert on the stack after the buffer chain has been added to the transmission queue, whereafter clones of the buffers are transmitted to the device layer outside the spinlock scope. As a further step in our effort to separate the roles of the node and link entities we also move the function tipc_link_xmit() to node.c, and rename it to tipc_node_xmit(). Reviewed-by: Ying Xue <ying.xue@windriver.com> Signed-off-by: Jon Maloy <jon.maloy@ericsson.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc/node.c')
-rw-r--r--net/tipc/node.c78
1 files changed, 78 insertions, 0 deletions
diff --git a/net/tipc/node.c b/net/tipc/node.c
index 19729645d494..ad759bb034e7 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -563,6 +563,84 @@ msg_full:
563 return -EMSGSIZE; 563 return -EMSGSIZE;
564} 564}
565 565
566static struct tipc_link *tipc_node_select_link(struct tipc_node *n, int sel,
567 int *bearer_id,
568 struct tipc_media_addr **maddr)
569{
570 int id = n->active_links[sel & 1];
571
572 if (unlikely(id < 0))
573 return NULL;
574
575 *bearer_id = id;
576 *maddr = &n->links[id].maddr;
577 return n->links[id].link;
578}
579
580/**
581 * tipc_node_xmit() is the general link level function for message sending
582 * @net: the applicable net namespace
583 * @list: chain of buffers containing message
584 * @dnode: address of destination node
585 * @selector: a number used for deterministic link selection
586 * Consumes the buffer chain, except when returning -ELINKCONG
587 * Returns 0 if success, otherwise errno: -ELINKCONG,-EHOSTUNREACH,-EMSGSIZE
588 */
589int tipc_node_xmit(struct net *net, struct sk_buff_head *list,
590 u32 dnode, int selector)
591{
592 struct tipc_link *l = NULL;
593 struct tipc_node *n;
594 struct sk_buff_head xmitq;
595 struct tipc_media_addr *maddr;
596 int bearer_id;
597 int rc = -EHOSTUNREACH;
598
599 __skb_queue_head_init(&xmitq);
600 n = tipc_node_find(net, dnode);
601 if (likely(n)) {
602 tipc_node_lock(n);
603 l = tipc_node_select_link(n, selector, &bearer_id, &maddr);
604 if (likely(l))
605 rc = tipc_link_xmit(l, list, &xmitq);
606 if (unlikely(rc == -ENOBUFS))
607 tipc_link_reset(l);
608 tipc_node_unlock(n);
609 tipc_node_put(n);
610 }
611 if (likely(!rc)) {
612 tipc_bearer_xmit(net, bearer_id, &xmitq, maddr);
613 return 0;
614 }
615 if (likely(in_own_node(net, dnode))) {
616 tipc_sk_rcv(net, list);
617 return 0;
618 }
619 return rc;
620}
621
622/* tipc_node_xmit_skb(): send single buffer to destination
623 * Buffers sent via this functon are generally TIPC_SYSTEM_IMPORTANCE
624 * messages, which will not be rejected
625 * The only exception is datagram messages rerouted after secondary
626 * lookup, which are rare and safe to dispose of anyway.
627 * TODO: Return real return value, and let callers use
628 * tipc_wait_for_sendpkt() where applicable
629 */
630int tipc_node_xmit_skb(struct net *net, struct sk_buff *skb, u32 dnode,
631 u32 selector)
632{
633 struct sk_buff_head head;
634 int rc;
635
636 skb_queue_head_init(&head);
637 __skb_queue_tail(&head, skb);
638 rc = tipc_node_xmit(net, &head, dnode, selector);
639 if (rc == -ELINKCONG)
640 kfree_skb(skb);
641 return 0;
642}
643
566int tipc_nl_node_dump(struct sk_buff *skb, struct netlink_callback *cb) 644int tipc_nl_node_dump(struct sk_buff *skb, struct netlink_callback *cb)
567{ 645{
568 int err; 646 int err;