Commit 7214bcf8 authored by Jon Paul Maloy's avatar Jon Paul Maloy Committed by David S. Miller

tipc: eliminate redundant buffer cloning at transmission

Since all packet transmitters (link, bcast, discovery) are now sending
consumable buffer clones to the bearer layer, we can remove the
redundant buffer cloning that is perfomed in the lower level functions
tipc_l2_send_msg() and tipc_udp_send_msg().
Signed-off-by: default avatarJon Maloy <jon.maloy@ericsson.com>
Reviewed-by: default avatarYing Xue <ying.xue@windriver.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 60852d67
...@@ -414,10 +414,9 @@ void tipc_disable_l2_media(struct tipc_bearer *b) ...@@ -414,10 +414,9 @@ void tipc_disable_l2_media(struct tipc_bearer *b)
* @b_ptr: the bearer through which the packet is to be sent * @b_ptr: the bearer through which the packet is to be sent
* @dest: peer destination address * @dest: peer destination address
*/ */
int tipc_l2_send_msg(struct net *net, struct sk_buff *buf, int tipc_l2_send_msg(struct net *net, struct sk_buff *skb,
struct tipc_bearer *b, struct tipc_media_addr *dest) struct tipc_bearer *b, struct tipc_media_addr *dest)
{ {
struct sk_buff *clone;
struct net_device *dev; struct net_device *dev;
int delta; int delta;
...@@ -425,23 +424,19 @@ int tipc_l2_send_msg(struct net *net, struct sk_buff *buf, ...@@ -425,23 +424,19 @@ int tipc_l2_send_msg(struct net *net, struct sk_buff *buf,
if (!dev) if (!dev)
return 0; return 0;
clone = skb_clone(buf, GFP_ATOMIC); delta = dev->hard_header_len - skb_headroom(skb);
if (!clone)
return 0;
delta = dev->hard_header_len - skb_headroom(buf);
if ((delta > 0) && if ((delta > 0) &&
pskb_expand_head(clone, SKB_DATA_ALIGN(delta), 0, GFP_ATOMIC)) { pskb_expand_head(skb, SKB_DATA_ALIGN(delta), 0, GFP_ATOMIC)) {
kfree_skb(clone); kfree_skb(skb);
return 0; return 0;
} }
skb_reset_network_header(clone); skb_reset_network_header(skb);
clone->dev = dev; skb->dev = dev;
clone->protocol = htons(ETH_P_TIPC); skb->protocol = htons(ETH_P_TIPC);
dev_hard_header(clone, dev, ETH_P_TIPC, dest->value, dev_hard_header(skb, dev, ETH_P_TIPC, dest->value,
dev->dev_addr, clone->len); dev->dev_addr, skb->len);
dev_queue_xmit(clone); dev_queue_xmit(skb);
return 0; return 0;
} }
...@@ -491,8 +486,6 @@ void tipc_bearer_xmit_skb(struct net *net, u32 bearer_id, ...@@ -491,8 +486,6 @@ void tipc_bearer_xmit_skb(struct net *net, u32 bearer_id,
if (likely(b)) if (likely(b))
b->media->send_msg(net, skb, b, dest); b->media->send_msg(net, skb, b, dest);
rcu_read_unlock(); rcu_read_unlock();
/* Until we remove cloning in tipc_l2_send_msg(): */
kfree_skb(skb);
} }
/* tipc_bearer_xmit() -send buffer to destination over bearer /* tipc_bearer_xmit() -send buffer to destination over bearer
...@@ -514,8 +507,6 @@ void tipc_bearer_xmit(struct net *net, u32 bearer_id, ...@@ -514,8 +507,6 @@ void tipc_bearer_xmit(struct net *net, u32 bearer_id,
skb_queue_walk_safe(xmitq, skb, tmp) { skb_queue_walk_safe(xmitq, skb, tmp) {
__skb_dequeue(xmitq); __skb_dequeue(xmitq);
b->media->send_msg(net, skb, b, dst); b->media->send_msg(net, skb, b, dst);
/* Until we remove cloning in tipc_l2_send_msg(): */
kfree_skb(skb);
} }
} }
rcu_read_unlock(); rcu_read_unlock();
...@@ -541,8 +532,6 @@ void tipc_bearer_bc_xmit(struct net *net, u32 bearer_id, ...@@ -541,8 +532,6 @@ void tipc_bearer_bc_xmit(struct net *net, u32 bearer_id,
msg_set_mc_netid(hdr, net_id); msg_set_mc_netid(hdr, net_id);
__skb_dequeue(xmitq); __skb_dequeue(xmitq);
b->media->send_msg(net, skb, b, &b->bcast_addr); b->media->send_msg(net, skb, b, &b->bcast_addr);
/* Until we remove cloning in tipc_l2_send_msg(): */
kfree_skb(skb);
} }
} }
rcu_read_unlock(); rcu_read_unlock();
......
...@@ -155,14 +155,12 @@ static int tipc_udp_send_msg(struct net *net, struct sk_buff *skb, ...@@ -155,14 +155,12 @@ static int tipc_udp_send_msg(struct net *net, struct sk_buff *skb,
struct udp_bearer *ub; struct udp_bearer *ub;
struct udp_media_addr *dst = (struct udp_media_addr *)&dest->value; struct udp_media_addr *dst = (struct udp_media_addr *)&dest->value;
struct udp_media_addr *src = (struct udp_media_addr *)&b->addr.value; struct udp_media_addr *src = (struct udp_media_addr *)&b->addr.value;
struct sk_buff *clone;
struct rtable *rt; struct rtable *rt;
if (skb_headroom(skb) < UDP_MIN_HEADROOM) if (skb_headroom(skb) < UDP_MIN_HEADROOM)
pskb_expand_head(skb, UDP_MIN_HEADROOM, 0, GFP_ATOMIC); pskb_expand_head(skb, UDP_MIN_HEADROOM, 0, GFP_ATOMIC);
clone = skb_clone(skb, GFP_ATOMIC); skb_set_inner_protocol(skb, htons(ETH_P_TIPC));
skb_set_inner_protocol(clone, htons(ETH_P_TIPC));
ub = rcu_dereference_rtnl(b->media_ptr); ub = rcu_dereference_rtnl(b->media_ptr);
if (!ub) { if (!ub) {
err = -ENODEV; err = -ENODEV;
...@@ -172,7 +170,7 @@ static int tipc_udp_send_msg(struct net *net, struct sk_buff *skb, ...@@ -172,7 +170,7 @@ static int tipc_udp_send_msg(struct net *net, struct sk_buff *skb,
struct flowi4 fl = { struct flowi4 fl = {
.daddr = dst->ipv4.s_addr, .daddr = dst->ipv4.s_addr,
.saddr = src->ipv4.s_addr, .saddr = src->ipv4.s_addr,
.flowi4_mark = clone->mark, .flowi4_mark = skb->mark,
.flowi4_proto = IPPROTO_UDP .flowi4_proto = IPPROTO_UDP
}; };
rt = ip_route_output_key(net, &fl); rt = ip_route_output_key(net, &fl);
...@@ -181,7 +179,7 @@ static int tipc_udp_send_msg(struct net *net, struct sk_buff *skb, ...@@ -181,7 +179,7 @@ static int tipc_udp_send_msg(struct net *net, struct sk_buff *skb,
goto tx_error; goto tx_error;
} }
ttl = ip4_dst_hoplimit(&rt->dst); ttl = ip4_dst_hoplimit(&rt->dst);
err = udp_tunnel_xmit_skb(rt, ub->ubsock->sk, clone, err = udp_tunnel_xmit_skb(rt, ub->ubsock->sk, skb,
src->ipv4.s_addr, src->ipv4.s_addr,
dst->ipv4.s_addr, 0, ttl, 0, dst->ipv4.s_addr, 0, ttl, 0,
src->udp_port, dst->udp_port, src->udp_port, dst->udp_port,
...@@ -204,7 +202,7 @@ static int tipc_udp_send_msg(struct net *net, struct sk_buff *skb, ...@@ -204,7 +202,7 @@ static int tipc_udp_send_msg(struct net *net, struct sk_buff *skb,
if (err) if (err)
goto tx_error; goto tx_error;
ttl = ip6_dst_hoplimit(ndst); ttl = ip6_dst_hoplimit(ndst);
err = udp_tunnel6_xmit_skb(ndst, ub->ubsock->sk, clone, err = udp_tunnel6_xmit_skb(ndst, ub->ubsock->sk, skb,
ndst->dev, &src->ipv6, ndst->dev, &src->ipv6,
&dst->ipv6, 0, ttl, src->udp_port, &dst->ipv6, 0, ttl, src->udp_port,
dst->udp_port, false); dst->udp_port, false);
...@@ -213,7 +211,7 @@ static int tipc_udp_send_msg(struct net *net, struct sk_buff *skb, ...@@ -213,7 +211,7 @@ static int tipc_udp_send_msg(struct net *net, struct sk_buff *skb,
return err; return err;
tx_error: tx_error:
kfree_skb(clone); kfree_skb(skb);
return err; return err;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment