[ovs-dev] [PATCH v4 13/28] datapath: backport: ip_tunnel: Move stats update to iptunnel_xmit()

Pravin B Shelar pshelar at ovn.org
Fri Jul 8 00:23:49 UTC 2016


Upstream commit:
    commit 039f50629b7f860f36644ed1f34b27da9aa62f43
    Author: Pravin B Shelar <pshelar at ovn.org>

    ip_tunnel: Move stats update to iptunnel_xmit()

    By moving stats update into iptunnel_xmit(), we can simplify
    iptunnel_xmit() usage. With this change there is no need to
    call another function (iptunnel_xmit_stats()) to update stats
    in tunnel xmit code path.

    Signed-off-by: Pravin B Shelar <pshelar at ovn.org>
    Signed-off-by: David S. Miller <davem at davemloft.net>

Signed-off-by: Pravin B Shelar <pshelar at ovn.org>
---
 datapath/linux/compat/geneve.c                 |  9 ++---
 datapath/linux/compat/include/net/ip6_tunnel.h |  8 ++---
 datapath/linux/compat/include/net/ip_tunnels.h | 46 +++++++++-----------------
 datapath/linux/compat/include/net/udp_tunnel.h |  2 +-
 datapath/linux/compat/ip_gre.c                 |  6 ++--
 datapath/linux/compat/ip_tunnels_core.c        |  6 ++--
 datapath/linux/compat/lisp.c                   |  9 +++--
 datapath/linux/compat/stt.c                    | 28 +++++++---------
 datapath/linux/compat/udp_tunnel.c             |  5 ++-
 datapath/linux/compat/vxlan.c                  | 23 +++++--------
 10 files changed, 54 insertions(+), 88 deletions(-)

diff --git a/datapath/linux/compat/geneve.c b/datapath/linux/compat/geneve.c
index d8e9d57..6aa71c0 100644
--- a/datapath/linux/compat/geneve.c
+++ b/datapath/linux/compat/geneve.c
@@ -703,12 +703,9 @@ netdev_tx_t rpl_geneve_xmit(struct sk_buff *skb)
 		ttl = ttl ? : ip4_dst_hoplimit(&rt->dst);
 		df = 0;
 	}
-	err = udp_tunnel_xmit_skb(rt, gs->sock->sk, skb, fl4.saddr, fl4.daddr,
-				  tos, ttl, df, sport, geneve->dst_port,
-				  !net_eq(geneve->net, dev_net(geneve->dev)),
-				  !udp_csum);
-
-	iptunnel_xmit_stats(err, &dev->stats, (struct pcpu_sw_netstats __percpu *) dev->tstats);
+	udp_tunnel_xmit_skb(rt, gs->sock->sk, skb, fl4.saddr, fl4.daddr,
+			    tos, ttl, df, sport, geneve->dst_port,
+			    !net_eq(geneve->net, dev_net(geneve->dev)), !udp_csum);
 	return NETDEV_TX_OK;
 
 tx_error:
diff --git a/datapath/linux/compat/include/net/ip6_tunnel.h b/datapath/linux/compat/include/net/ip6_tunnel.h
index ce65087..b807c2c 100644
--- a/datapath/linux/compat/include/net/ip6_tunnel.h
+++ b/datapath/linux/compat/include/net/ip6_tunnel.h
@@ -22,12 +22,10 @@ static inline void ip6tunnel_xmit(struct sock *sk, struct sk_buff *skb,
 #else
 	err = ip6_local_out(skb);
 #endif
-	if (net_xmit_eval(err) != 0)
-		pkt_len = net_xmit_eval(err);
-	else
-		pkt_len = err;
+	if (net_xmit_eval(err))
+		pkt_len = -1;
 
-	iptunnel_xmit_stats(pkt_len, &dev->stats, (struct pcpu_sw_netstats __percpu *)dev->tstats);
+	iptunnel_xmit_stats(dev, pkt_len);
 }
 
 #endif
diff --git a/datapath/linux/compat/include/net/ip_tunnels.h b/datapath/linux/compat/include/net/ip_tunnels.h
index bc50a3b..d79d498 100644
--- a/datapath/linux/compat/include/net/ip_tunnels.h
+++ b/datapath/linux/compat/include/net/ip_tunnels.h
@@ -52,9 +52,9 @@ struct sk_buff *rpl_iptunnel_handle_offloads(struct sk_buff *skb,
 #endif
 
 #define iptunnel_xmit rpl_iptunnel_xmit
-int rpl_iptunnel_xmit(struct sock *sk, struct rtable *rt, struct sk_buff *skb,
-		      __be32 src, __be32 dst, __u8 proto, __u8 tos, __u8 ttl,
-		      __be16 df, bool xnet);
+void rpl_iptunnel_xmit(struct sock *sk, struct rtable *rt, struct sk_buff *skb,
+		       __be32 src, __be32 dst, __u8 proto, __u8 tos, __u8 ttl,
+		       __be16 df, bool xnet);
 
 #ifndef TUNNEL_CSUM
 #define TUNNEL_CSUM	__cpu_to_be16(0x01)
@@ -258,41 +258,27 @@ static inline u8 ip_tunnel_ecn_encap(u8 tos, const struct iphdr *iph,
 	return INET_ECN_encapsulate(tos, inner);
 }
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,39)
-#define iptunnel_xmit_stats(err, stats, dummy)		\
-do {							\
-	if (err > 0) {					\
-		(stats)->tx_bytes += err;		\
-		(stats)->tx_packets++;			\
-	} else if (err < 0) {				\
-		(stats)->tx_errors++;			\
-		(stats)->tx_aborted_errors++;		\
-	} else {					\
-		(stats)->tx_dropped++;			\
-	}						\
-} while (0)
-
-#else
-#define iptunnel_xmit_stats rpl_iptunnel_xmit_stats
-static inline void iptunnel_xmit_stats(int err,
-		struct net_device_stats *err_stats,
-		struct pcpu_sw_netstats __percpu *stats)
+static inline void iptunnel_xmit_stats(struct net_device *dev, int pkt_len)
 {
-	if (err > 0) {
-		struct pcpu_sw_netstats *tstats = this_cpu_ptr(stats);
+	if (pkt_len > 0) {
+		struct pcpu_sw_netstats *tstats = get_cpu_ptr(dev->tstats);
 
 		u64_stats_update_begin(&tstats->syncp);
-		tstats->tx_bytes += err;
+		tstats->tx_bytes += pkt_len;
 		tstats->tx_packets++;
 		u64_stats_update_end(&tstats->syncp);
-	} else if (err < 0) {
-		err_stats->tx_errors++;
-		err_stats->tx_aborted_errors++;
+		put_cpu_ptr(tstats);
 	} else {
-		err_stats->tx_dropped++;
+		struct net_device_stats *err_stats = &dev->stats;
+
+		if (pkt_len < 0) {
+			err_stats->tx_errors++;
+			err_stats->tx_aborted_errors++;
+		} else {
+			err_stats->tx_dropped++;
+		}
 	}
 }
-#endif
 
 #define ip_tunnel_init rpl_ip_tunnel_init
 int rpl_ip_tunnel_init(struct net_device *dev);
diff --git a/datapath/linux/compat/include/net/udp_tunnel.h b/datapath/linux/compat/include/net/udp_tunnel.h
index 3922e24..aaa294a 100644
--- a/datapath/linux/compat/include/net/udp_tunnel.h
+++ b/datapath/linux/compat/include/net/udp_tunnel.h
@@ -99,7 +99,7 @@ void rpl_setup_udp_tunnel_sock(struct net *net, struct socket *sock,
 
 /* Transmit the skb using UDP encapsulation. */
 #define udp_tunnel_xmit_skb rpl_udp_tunnel_xmit_skb
-int rpl_udp_tunnel_xmit_skb(struct rtable *rt,
+void rpl_udp_tunnel_xmit_skb(struct rtable *rt,
 			    struct sock *sk, struct sk_buff *skb,
 			    __be32 src, __be32 dst, __u8 tos, __u8 ttl,
 			    __be16 df, __be16 src_port, __be16 dst_port,
diff --git a/datapath/linux/compat/ip_gre.c b/datapath/linux/compat/ip_gre.c
index 6d7f653..2c3ba28 100644
--- a/datapath/linux/compat/ip_gre.c
+++ b/datapath/linux/compat/ip_gre.c
@@ -327,10 +327,8 @@ netdev_tx_t rpl_gre_fb_xmit(struct sk_buff *skb)
 		     tunnel_id_to_key(tun_info->key.tun_id), 0);
 
 	df = key->tun_flags & TUNNEL_DONT_FRAGMENT ?  htons(IP_DF) : 0;
-	err = iptunnel_xmit(skb->sk, rt, skb, fl.saddr,
-			    key->u.ipv4.dst, IPPROTO_GRE,
-			    key->tos, key->ttl, df, false);
-	iptunnel_xmit_stats(err, &dev->stats, (struct pcpu_sw_netstats __percpu *)dev->tstats);
+	iptunnel_xmit(skb->sk, rt, skb, fl.saddr, key->u.ipv4.dst, IPPROTO_GRE,
+		      key->tos, key->ttl, df, false);
 	return NETDEV_TX_OK;
 
 err_free_rt:
diff --git a/datapath/linux/compat/ip_tunnels_core.c b/datapath/linux/compat/ip_tunnels_core.c
index 9b72f4a..df65ce3 100644
--- a/datapath/linux/compat/ip_tunnels_core.c
+++ b/datapath/linux/compat/ip_tunnels_core.c
@@ -38,10 +38,11 @@
 #include "vport-netdev.h"
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(3,18,0)
-int rpl_iptunnel_xmit(struct sock *sk, struct rtable *rt, struct sk_buff *skb,
+void rpl_iptunnel_xmit(struct sock *sk, struct rtable *rt, struct sk_buff *skb,
                       __be32 src, __be32 dst, __u8 proto, __u8 tos, __u8 ttl,
                       __be16 df, bool xnet)
 {
+	struct net_device *dev = skb->dev;
 	int pkt_len = skb->len;
 	struct iphdr *iph;
 	int err;
@@ -83,7 +84,7 @@ int rpl_iptunnel_xmit(struct sock *sk, struct rtable *rt, struct sk_buff *skb,
 	err = ip_local_out(skb);
 	if (unlikely(net_xmit_eval(err)))
 		pkt_len = 0;
-	return pkt_len;
+	iptunnel_xmit_stats(dev, pkt_len);
 }
 EXPORT_SYMBOL_GPL(rpl_iptunnel_xmit);
 #endif
@@ -111,7 +112,6 @@ int ovs_iptunnel_handle_offloads(struct sk_buff *skb,
 
 	OVS_GSO_CB(skb)->fix_segment = fix_segment;
 #endif
-
 	if (skb_is_gso(skb)) {
 		err = skb_unclone(skb, GFP_ATOMIC);
 		if (unlikely(err))
diff --git a/datapath/linux/compat/lisp.c b/datapath/linux/compat/lisp.c
index 01c4f59..3cb916d 100644
--- a/datapath/linux/compat/lisp.c
+++ b/datapath/linux/compat/lisp.c
@@ -358,12 +358,11 @@ netdev_tx_t rpl_lisp_xmit(struct sk_buff *skb)
 	ovs_skb_set_inner_protocol(skb, skb->protocol);
 
 	df = tun_key->tun_flags & TUNNEL_DONT_FRAGMENT ? htons(IP_DF) : 0;
-	err = udp_tunnel_xmit_skb(rt, lisp_dev->sock->sk, skb,
-			fl.saddr, tun_key->u.ipv4.dst,
-			tun_key->tos, tun_key->ttl,
-			df, src_port, dst_port, false, true);
+	udp_tunnel_xmit_skb(rt, lisp_dev->sock->sk, skb,
+			    fl.saddr, tun_key->u.ipv4.dst,
+			    tun_key->tos, tun_key->ttl,
+			    df, src_port, dst_port, false, true);
 
-	iptunnel_xmit_stats(err, &dev->stats, (struct pcpu_sw_netstats __percpu *)dev->tstats);
 	return NETDEV_TX_OK;
 
 err_free_rt:
diff --git a/datapath/linux/compat/stt.c b/datapath/linux/compat/stt.c
index a8c7eae..1a3cf76 100644
--- a/datapath/linux/compat/stt.c
+++ b/datapath/linux/compat/stt.c
@@ -851,11 +851,9 @@ error:
 	return ERR_PTR(err);
 }
 
-static int skb_list_xmit(struct rtable *rt, struct sk_buff *skb, __be32 src,
-			 __be32 dst, __u8 tos, __u8 ttl, __be16 df)
+static void skb_list_xmit(struct rtable *rt, struct sk_buff *skb, __be32 src,
+			  __be32 dst, __u8 tos, __u8 ttl, __be16 df)
 {
-	int len = 0;
-
 	while (skb) {
 		struct sk_buff *next = skb->next;
 
@@ -863,12 +861,11 @@ static int skb_list_xmit(struct rtable *rt, struct sk_buff *skb, __be32 src,
 			dst_clone(&rt->dst);
 
 		skb->next = NULL;
-		len += iptunnel_xmit(NULL, rt, skb, src, dst, IPPROTO_TCP,
-				     tos, ttl, df, false);
+		iptunnel_xmit(NULL, rt, skb, src, dst, IPPROTO_TCP,
+			      tos, ttl, df, false);
 
 		skb = next;
 	}
-	return len;
 }
 
 static u8 parse_ipv6_l4_proto(struct sk_buff *skb)
@@ -909,9 +906,9 @@ static u8 skb_get_l4_proto(struct sk_buff *skb, __be16 l3_proto)
 }
 
 static int stt_xmit_skb(struct sk_buff *skb, struct rtable *rt,
-		 __be32 src, __be32 dst, __u8 tos,
-		 __u8 ttl, __be16 df, __be16 src_port, __be16 dst_port,
-		 __be64 tun_id)
+			__be32 src, __be32 dst, __u8 tos,
+			__u8 ttl, __be16 df, __be16 src_port, __be16 dst_port,
+			__be64 tun_id)
 {
 	struct ethhdr *eh = eth_hdr(skb);
 	int ret = 0, min_headroom;
@@ -966,13 +963,13 @@ static int stt_xmit_skb(struct sk_buff *skb, struct rtable *rt,
 		}
 
 		/* Push IP header. */
-		ret += skb_list_xmit(rt, skb, src, dst, tos, ttl, df);
+		skb_list_xmit(rt, skb, src, dst, tos, ttl, df);
 
 next:
 		skb = next_skb;
 	}
 
-	return ret;
+	return 0;
 
 err_free_rt:
 	ip_rt_put(rt);
@@ -1030,10 +1027,9 @@ netdev_tx_t ovs_stt_xmit(struct sk_buff *skb)
 	sport = udp_flow_src_port(net, skb, 1, USHRT_MAX, true);
 	skb->ignore_df = 1;
 
-	err = stt_xmit_skb(skb, rt, fl.saddr, tun_key->u.ipv4.dst,
-			    tun_key->tos, tun_key->ttl,
-			    df, sport, dport, tun_key->tun_id);
-	iptunnel_xmit_stats(err, &dev->stats, (struct pcpu_sw_netstats __percpu *)dev->tstats);
+	stt_xmit_skb(skb, rt, fl.saddr, tun_key->u.ipv4.dst,
+		    tun_key->tos, tun_key->ttl,
+		    df, sport, dport, tun_key->tun_id);
 	return NETDEV_TX_OK;
 error:
 	kfree_skb(skb);
diff --git a/datapath/linux/compat/udp_tunnel.c b/datapath/linux/compat/udp_tunnel.c
index 0ad3c2a..7c0d34b 100644
--- a/datapath/linux/compat/udp_tunnel.c
+++ b/datapath/linux/compat/udp_tunnel.c
@@ -166,7 +166,7 @@ void ovs_udp_csum_gso(struct sk_buff *skb)
 }
 EXPORT_SYMBOL_GPL(ovs_udp_csum_gso);
 
-int rpl_udp_tunnel_xmit_skb(struct rtable *rt, struct sock *sk,
+void rpl_udp_tunnel_xmit_skb(struct rtable *rt, struct sock *sk,
 			    struct sk_buff *skb, __be32 src, __be32 dst,
 			    __u8 tos, __u8 ttl, __be16 df, __be16 src_port,
 			    __be16 dst_port, bool xnet, bool nocheck)
@@ -183,8 +183,7 @@ int rpl_udp_tunnel_xmit_skb(struct rtable *rt, struct sock *sk,
 
 	udp_set_csum(nocheck, skb, src, dst, skb->len);
 
-	return iptunnel_xmit(sk, rt, skb, src, dst, IPPROTO_UDP,
-			     tos, ttl, df, xnet);
+	iptunnel_xmit(sk, rt, skb, src, dst, IPPROTO_UDP, tos, ttl, df, xnet);
 }
 EXPORT_SYMBOL_GPL(rpl_udp_tunnel_xmit_skb);
 
diff --git a/datapath/linux/compat/vxlan.c b/datapath/linux/compat/vxlan.c
index 3776990..6129e5c 100644
--- a/datapath/linux/compat/vxlan.c
+++ b/datapath/linux/compat/vxlan.c
@@ -1207,9 +1207,10 @@ static int vxlan_xmit_skb(struct rtable *rt, struct sock *sk, struct sk_buff *sk
 
 	ovs_skb_set_inner_protocol(skb, htons(ETH_P_TEB));
 
-	return udp_tunnel_xmit_skb(rt, sk, skb, src, dst, tos,
-				   ttl, df, src_port, dst_port, xnet,
-				   !(vxflags & VXLAN_F_UDP_CSUM));
+	udp_tunnel_xmit_skb(rt, sk, skb, src, dst, tos,
+			    ttl, df, src_port, dst_port, xnet,
+			    !(vxflags & VXLAN_F_UDP_CSUM));
+	return 0;
 }
 
 static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
@@ -1342,18 +1343,10 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
 
 		tos = ip_tunnel_ecn_encap(tos, old_iph, skb);
 		ttl = ttl ? : ip4_dst_hoplimit(&rt->dst);
-		err = vxlan_xmit_skb(rt, sk, skb, fl4.saddr,
-				     dst->sin.sin_addr.s_addr, tos, ttl, df,
-				     src_port, dst_port, htonl(vni << 8), md,
-				     !net_eq(vxlan->net, dev_net(vxlan->dev)),
-				     flags);
-		if (err < 0) {
-			/* skb is already freed. */
-			skb = NULL;
-			goto rt_tx_error;
-		}
-
-		iptunnel_xmit_stats(err, &dev->stats, (struct pcpu_sw_netstats __percpu *)dev->tstats);
+		vxlan_xmit_skb(rt, sk, skb, fl4.saddr,
+			       dst->sin.sin_addr.s_addr, tos, ttl, df,
+			       src_port, dst_port, htonl(vni << 8), md,
+			       !net_eq(vxlan->net, dev_net(vxlan->dev)), flags);
 #if IS_ENABLED(CONFIG_IPV6)
 	} else {
 		struct dst_entry *ndst;
-- 
1.9.1




More information about the dev mailing list