diff options
author | Jon Paul Maloy <jon.maloy@ericsson.com> | 2015-03-13 16:08:08 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-03-14 14:38:32 -0400 |
commit | c1336ee472f83a90ede01fdae095ed5d0a2934c9 (patch) | |
tree | 4178d007c524fe51262b3698150c63d38591b521 /net/tipc/link.c | |
parent | 1149557d64c97dc9adf3103347a1c0e8c06d3b89 (diff) |
tipc: extract bundled buffers by cloning instead of copying
When we currently extract a bundled buffer from a message bundle in
the function tipc_msg_extract(), we allocate a new buffer and explicitly
copy the linear data area.
This is unnecessary, since we can just clone the buffer and do
skb_pull() on the clone to move the data pointer to the correct
position.
This is what we do in this commit.
Reviewed-by: Erik Hugne <erik.hugne@ericsson.com>
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/link.c')
-rw-r--r-- | net/tipc/link.c | 45 |
1 files changed, 12 insertions, 33 deletions
diff --git a/net/tipc/link.c b/net/tipc/link.c index 8c6639d107fc..56c39b1a53a9 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * net/tipc/link.c: TIPC link code | 2 | * net/tipc/link.c: TIPC link code |
3 | * | 3 | * |
4 | * Copyright (c) 1996-2007, 2012-2014, Ericsson AB | 4 | * Copyright (c) 1996-2007, 2012-2015, Ericsson AB |
5 | * Copyright (c) 2004-2007, 2010-2013, Wind River Systems | 5 | * Copyright (c) 2004-2007, 2010-2013, Wind River Systems |
6 | * All rights reserved. | 6 | * All rights reserved. |
7 | * | 7 | * |
@@ -1117,7 +1117,7 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b_ptr) | |||
1117 | ackd = msg_ack(msg); | 1117 | ackd = msg_ack(msg); |
1118 | 1118 | ||
1119 | /* Release acked messages */ | 1119 | /* Release acked messages */ |
1120 | if (n_ptr->bclink.recv_permitted) | 1120 | if (likely(n_ptr->bclink.recv_permitted)) |
1121 | tipc_bclink_acknowledge(n_ptr, msg_bcast_ack(msg)); | 1121 | tipc_bclink_acknowledge(n_ptr, msg_bcast_ack(msg)); |
1122 | 1122 | ||
1123 | released = 0; | 1123 | released = 0; |
@@ -1712,45 +1712,24 @@ void tipc_link_dup_queue_xmit(struct tipc_link *l_ptr, | |||
1712 | } | 1712 | } |
1713 | } | 1713 | } |
1714 | 1714 | ||
1715 | /** | ||
1716 | * buf_extract - extracts embedded TIPC message from another message | ||
1717 | * @skb: encapsulating message buffer | ||
1718 | * @from_pos: offset to extract from | ||
1719 | * | ||
1720 | * Returns a new message buffer containing an embedded message. The | ||
1721 | * encapsulating buffer is left unchanged. | ||
1722 | */ | ||
1723 | static struct sk_buff *buf_extract(struct sk_buff *skb, u32 from_pos) | ||
1724 | { | ||
1725 | struct tipc_msg *msg = (struct tipc_msg *)(skb->data + from_pos); | ||
1726 | u32 size = msg_size(msg); | ||
1727 | struct sk_buff *eb; | ||
1728 | |||
1729 | eb = tipc_buf_acquire(size); | ||
1730 | if (eb) | ||
1731 | skb_copy_to_linear_data(eb, msg, size); | ||
1732 | return eb; | ||
1733 | } | ||
1734 | |||
1735 | /* tipc_link_dup_rcv(): Receive a tunnelled DUPLICATE_MSG packet. | 1715 | /* tipc_link_dup_rcv(): Receive a tunnelled DUPLICATE_MSG packet. |
1736 | * Owner node is locked. | 1716 | * Owner node is locked. |
1737 | */ | 1717 | */ |
1738 | static void tipc_link_dup_rcv(struct tipc_link *l_ptr, | 1718 | static void tipc_link_dup_rcv(struct tipc_link *link, |
1739 | struct sk_buff *t_buf) | 1719 | struct sk_buff *skb) |
1740 | { | 1720 | { |
1741 | struct sk_buff *buf; | 1721 | struct sk_buff *iskb; |
1722 | int pos = 0; | ||
1742 | 1723 | ||
1743 | if (!tipc_link_is_up(l_ptr)) | 1724 | if (!tipc_link_is_up(link)) |
1744 | return; | 1725 | return; |
1745 | 1726 | ||
1746 | buf = buf_extract(t_buf, INT_H_SIZE); | 1727 | if (!tipc_msg_extract(skb, &iskb, &pos)) { |
1747 | if (buf == NULL) { | ||
1748 | pr_warn("%sfailed to extract inner dup pkt\n", link_co_err); | 1728 | pr_warn("%sfailed to extract inner dup pkt\n", link_co_err); |
1749 | return; | 1729 | return; |
1750 | } | 1730 | } |
1751 | 1731 | /* Append buffer to deferred queue, if applicable: */ | |
1752 | /* Add buffer to deferred queue, if applicable: */ | 1732 | link_handle_out_of_seq_msg(link, iskb); |
1753 | link_handle_out_of_seq_msg(l_ptr, buf); | ||
1754 | } | 1733 | } |
1755 | 1734 | ||
1756 | /* tipc_link_failover_rcv(): Receive a tunnelled ORIGINAL_MSG packet | 1735 | /* tipc_link_failover_rcv(): Receive a tunnelled ORIGINAL_MSG packet |
@@ -1762,6 +1741,7 @@ static struct sk_buff *tipc_link_failover_rcv(struct tipc_link *l_ptr, | |||
1762 | struct tipc_msg *t_msg = buf_msg(t_buf); | 1741 | struct tipc_msg *t_msg = buf_msg(t_buf); |
1763 | struct sk_buff *buf = NULL; | 1742 | struct sk_buff *buf = NULL; |
1764 | struct tipc_msg *msg; | 1743 | struct tipc_msg *msg; |
1744 | int pos = 0; | ||
1765 | 1745 | ||
1766 | if (tipc_link_is_up(l_ptr)) | 1746 | if (tipc_link_is_up(l_ptr)) |
1767 | tipc_link_reset(l_ptr); | 1747 | tipc_link_reset(l_ptr); |
@@ -1773,8 +1753,7 @@ static struct sk_buff *tipc_link_failover_rcv(struct tipc_link *l_ptr, | |||
1773 | /* Should there be an inner packet? */ | 1753 | /* Should there be an inner packet? */ |
1774 | if (l_ptr->exp_msg_count) { | 1754 | if (l_ptr->exp_msg_count) { |
1775 | l_ptr->exp_msg_count--; | 1755 | l_ptr->exp_msg_count--; |
1776 | buf = buf_extract(t_buf, INT_H_SIZE); | 1756 | if (!tipc_msg_extract(t_buf, &buf, &pos)) { |
1777 | if (buf == NULL) { | ||
1778 | pr_warn("%sno inner failover pkt\n", link_co_err); | 1757 | pr_warn("%sno inner failover pkt\n", link_co_err); |
1779 | goto exit; | 1758 | goto exit; |
1780 | } | 1759 | } |