Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d71785ff authored by Paolo Abeni's avatar Paolo Abeni Committed by David S. Miller
Browse files

net: add dst_cache to ovs vxlan lwtunnel



In case of UDP traffic with datagram length
below MTU this give about 2% performance increase
when tunneling over ipv4 and about 60% when tunneling
over ipv6

Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
Suggested-and-acked-by: default avatarHannes Frederic Sowa <hannes@stressinduktion.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 0c1d70af
Loading
Loading
Loading
Loading
+8 −7
Original line number Diff line number Diff line
@@ -1775,7 +1775,7 @@ static struct rtable *vxlan_get_route(struct vxlan_dev *vxlan,
	/* when the ip_tunnel_info is availble, the tos used for lookup is
	 * packet independent, so we can use the cache
	 */
	if (dst_cache && !skb->mark && (!tos || info)) {
	if (!skb->mark && (!tos || info)) {
		use_cache = true;
		rt = dst_cache_get_ip4(dst_cache, saddr);
		if (rt)
@@ -1806,13 +1806,11 @@ static struct dst_entry *vxlan6_get_route(struct vxlan_dev *vxlan,
					  struct in6_addr *saddr,
					  struct dst_cache *dst_cache)
{
	bool use_cache = false;
	struct dst_entry *ndst;
	struct flowi6 fl6;
	int err;

	if (dst_cache && !skb->mark) {
		use_cache = true;
	if (!skb->mark) {
		ndst = dst_cache_get_ip6(dst_cache, saddr);
		if (ndst)
			return ndst;
@@ -1832,7 +1830,7 @@ static struct dst_entry *vxlan6_get_route(struct vxlan_dev *vxlan,
		return ERR_PTR(err);

	*saddr = fl6.saddr;
	if (use_cache)
	if (!skb->mark)
		dst_cache_set_ip6(dst_cache, ndst, saddr);
	return ndst;
}
@@ -1886,6 +1884,7 @@ static void vxlan_encap_bypass(struct sk_buff *skb, struct vxlan_dev *src_vxlan,
static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
			   struct vxlan_rdst *rdst, bool did_rsc)
{
	struct dst_cache *dst_cache;
	struct ip_tunnel_info *info;
	struct vxlan_dev *vxlan = netdev_priv(dev);
	struct sock *sk;
@@ -1910,6 +1909,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
		dst_port = rdst->remote_port ? rdst->remote_port : vxlan->cfg.dst_port;
		vni = rdst->remote_vni;
		dst = &rdst->remote_ip;
		dst_cache = &rdst->dst_cache;
	} else {
		if (!info) {
			WARN_ONCE(1, "%s: Missing encapsulation instructions\n",
@@ -1924,6 +1924,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
		else
			remote_ip.sin6.sin6_addr = info->key.u.ipv6.dst;
		dst = &remote_ip;
		dst_cache = &info->dst_cache;
	}

	if (vxlan_addr_any(dst)) {
@@ -1976,7 +1977,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
		rt = vxlan_get_route(vxlan, skb,
				     rdst ? rdst->remote_ifindex : 0, tos,
				     dst->sin.sin_addr.s_addr, &saddr,
				     rdst ? &rdst->dst_cache : NULL, info);
				     dst_cache, info);
		if (IS_ERR(rt)) {
			netdev_dbg(dev, "no route to %pI4\n",
				   &dst->sin.sin_addr.s_addr);
@@ -2029,7 +2030,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
		ndst = vxlan6_get_route(vxlan, skb,
					rdst ? rdst->remote_ifindex : 0,
					&dst->sin6.sin6_addr, &saddr,
					rdst ? &rdst->dst_cache : NULL);
					dst_cache);
		if (IS_ERR(ndst)) {
			netdev_dbg(dev, "no route to %pI6\n",
				   &dst->sin6.sin6_addr);
+1 −0
Original line number Diff line number Diff line
@@ -62,6 +62,7 @@ static inline int skb_metadata_dst_cmp(const struct sk_buff *skb_a,
		      sizeof(a->u.tun_info) + a->u.tun_info.options_len);
}

void metadata_dst_free(struct metadata_dst *);
struct metadata_dst *metadata_dst_alloc(u8 optslen, gfp_t flags);
struct metadata_dst __percpu *metadata_dst_alloc_percpu(u8 optslen, gfp_t flags);

+3 −0
Original line number Diff line number Diff line
@@ -58,6 +58,9 @@ struct ip_tunnel_key {

struct ip_tunnel_info {
	struct ip_tunnel_key	key;
#ifdef CONFIG_DST_CACHE
	struct dst_cache	dst_cache;
#endif
	u8			options_len;
	u8			mode;
};
+9 −1
Original line number Diff line number Diff line
@@ -265,7 +265,7 @@ struct dst_entry *dst_destroy(struct dst_entry * dst)
	lwtstate_put(dst->lwtstate);

	if (dst->flags & DST_METADATA)
		kfree(dst);
		metadata_dst_free((struct metadata_dst *)dst);
	else
		kmem_cache_free(dst->ops->kmem_cachep, dst);

@@ -395,6 +395,14 @@ struct metadata_dst *metadata_dst_alloc(u8 optslen, gfp_t flags)
}
EXPORT_SYMBOL_GPL(metadata_dst_alloc);

void metadata_dst_free(struct metadata_dst *md_dst)
{
#ifdef CONFIG_DST_CACHE
	dst_cache_destroy(&md_dst->u.tun_info.dst_cache);
#endif
	kfree(md_dst);
}

struct metadata_dst __percpu *metadata_dst_alloc_percpu(u8 optslen, gfp_t flags)
{
	int cpu;
+1 −0
Original line number Diff line number Diff line
@@ -10,6 +10,7 @@ config OPENVSWITCH
	select LIBCRC32C
	select MPLS
	select NET_MPLS_GSO
	select DST_CACHE
	---help---
	  Open vSwitch is a multilayer Ethernet switch targeted at virtualized
	  environments.  In addition to supporting a variety of features
Loading