Skip to content

Commit 468dfff

Browse files
Paolo Abenidavem330
authored andcommitted
geneve: add dst caching support
use generic dst implementation for both plain geneve devices and lwtunnels. In case of UDP traffic with datagram length below MTU this give about 2% performance increase for plain geneve tunnel over ipv4, about 65% performance increase for ipv6 tunnel. Signed-off-by: Paolo Abeni <pabeni@redhat.com> Suggested-and-Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent d71785f commit 468dfff

File tree

1 file changed

+39
-0
lines changed

1 file changed

+39
-0
lines changed

drivers/net/geneve.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ struct geneve_dev {
7272
bool collect_md;
7373
struct gro_cells gro_cells;
7474
u32 flags;
75+
struct dst_cache dst_cache;
7576
};
7677

7778
/* Geneve device flags */
@@ -297,13 +298,21 @@ static int geneve_init(struct net_device *dev)
297298
return err;
298299
}
299300

301+
err = dst_cache_init(&geneve->dst_cache, GFP_KERNEL);
302+
if (err) {
303+
free_percpu(dev->tstats);
304+
gro_cells_destroy(&geneve->gro_cells);
305+
return err;
306+
}
307+
300308
return 0;
301309
}
302310

303311
static void geneve_uninit(struct net_device *dev)
304312
{
305313
struct geneve_dev *geneve = netdev_priv(dev);
306314

315+
dst_cache_destroy(&geneve->dst_cache);
307316
gro_cells_destroy(&geneve->gro_cells);
308317
free_percpu(dev->tstats);
309318
}
@@ -753,7 +762,9 @@ static struct rtable *geneve_get_v4_rt(struct sk_buff *skb,
753762
struct ip_tunnel_info *info)
754763
{
755764
struct geneve_dev *geneve = netdev_priv(dev);
765+
struct dst_cache *dst_cache;
756766
struct rtable *rt = NULL;
767+
bool use_cache = true;
757768
__u8 tos;
758769

759770
memset(fl4, 0, sizeof(*fl4));
@@ -764,16 +775,26 @@ static struct rtable *geneve_get_v4_rt(struct sk_buff *skb,
764775
fl4->daddr = info->key.u.ipv4.dst;
765776
fl4->saddr = info->key.u.ipv4.src;
766777
fl4->flowi4_tos = RT_TOS(info->key.tos);
778+
dst_cache = &info->dst_cache;
767779
} else {
768780
tos = geneve->tos;
769781
if (tos == 1) {
770782
const struct iphdr *iip = ip_hdr(skb);
771783

772784
tos = ip_tunnel_get_dsfield(iip, skb);
785+
use_cache = false;
773786
}
774787

775788
fl4->flowi4_tos = RT_TOS(tos);
776789
fl4->daddr = geneve->remote.sin.sin_addr.s_addr;
790+
dst_cache = &geneve->dst_cache;
791+
}
792+
793+
use_cache = use_cache && !skb->mark;
794+
if (use_cache) {
795+
rt = dst_cache_get_ip4(dst_cache, &fl4->saddr);
796+
if (rt)
797+
return rt;
777798
}
778799

779800
rt = ip_route_output_key(geneve->net, fl4);
@@ -786,6 +807,8 @@ static struct rtable *geneve_get_v4_rt(struct sk_buff *skb,
786807
ip_rt_put(rt);
787808
return ERR_PTR(-ELOOP);
788809
}
810+
if (use_cache)
811+
dst_cache_set_ip4(dst_cache, &rt->dst, fl4->saddr);
789812
return rt;
790813
}
791814

@@ -798,6 +821,8 @@ static struct dst_entry *geneve_get_v6_dst(struct sk_buff *skb,
798821
struct geneve_dev *geneve = netdev_priv(dev);
799822
struct geneve_sock *gs6 = geneve->sock6;
800823
struct dst_entry *dst = NULL;
824+
struct dst_cache *dst_cache;
825+
bool use_cache = true;
801826
__u8 prio;
802827

803828
memset(fl6, 0, sizeof(*fl6));
@@ -808,16 +833,26 @@ static struct dst_entry *geneve_get_v6_dst(struct sk_buff *skb,
808833
fl6->daddr = info->key.u.ipv6.dst;
809834
fl6->saddr = info->key.u.ipv6.src;
810835
fl6->flowi6_tos = RT_TOS(info->key.tos);
836+
dst_cache = &info->dst_cache;
811837
} else {
812838
prio = geneve->tos;
813839
if (prio == 1) {
814840
const struct iphdr *iip = ip_hdr(skb);
815841

816842
prio = ip_tunnel_get_dsfield(iip, skb);
843+
use_cache = false;
817844
}
818845

819846
fl6->flowi6_tos = RT_TOS(prio);
820847
fl6->daddr = geneve->remote.sin6.sin6_addr;
848+
dst_cache = &geneve->dst_cache;
849+
}
850+
851+
use_cache = use_cache && !skb->mark;
852+
if (use_cache) {
853+
dst = dst_cache_get_ip6(dst_cache, &fl6->saddr);
854+
if (dst)
855+
return dst;
821856
}
822857

823858
if (ipv6_stub->ipv6_dst_lookup(geneve->net, gs6->sock->sk, &dst, fl6)) {
@@ -830,6 +865,8 @@ static struct dst_entry *geneve_get_v6_dst(struct sk_buff *skb,
830865
return ERR_PTR(-ELOOP);
831866
}
832867

868+
if (use_cache)
869+
dst_cache_set_ip6(dst_cache, dst, &fl6->saddr);
833870
return dst;
834871
}
835872
#endif
@@ -1272,6 +1309,8 @@ static int geneve_configure(struct net *net, struct net_device *dev,
12721309
return -EPERM;
12731310
}
12741311

1312+
dst_cache_reset(&geneve->dst_cache);
1313+
12751314
err = register_netdevice(dev);
12761315
if (err)
12771316
return err;

0 commit comments

Comments
 (0)