* [PATCH net-next 1/2] ipv6: sr: expand skb head only if necessary
2017-03-24 9:46 [PATCH net-next 0/2] Performances improvement for IPv6 Segment Routing David Lebrun
@ 2017-03-24 9:46 ` David Lebrun
2017-03-24 9:46 ` [PATCH net-next 2/2] ipv6: sr: use dst_cache in seg6_input David Lebrun
2017-03-24 21:48 ` [PATCH net-next 0/2] Performances improvement for IPv6 Segment Routing David Miller
2 siblings, 0 replies; 5+ messages in thread
From: David Lebrun @ 2017-03-24 9:46 UTC (permalink / raw)
To: netdev; +Cc: David Lebrun
To insert or encapsulate a packet with an SRH, we need a large enough skb
headroom. Currently, we are using pskb_expand_head to inconditionally increase
the size of the headroom by the amount needed by the SRH (and IPv6 header).
If this reallocation is performed by another CPU than the one that initially
allocated the skb, then when the initial CPU kfree the skb, it will enter the
__slab_free slowpath, impacting performances.
This patch replaces pskb_expand_head with skb_cow_head, that will reallocate the
skb head only if the headroom is not large enough.
Performances for SRH encapsulation before the patch:
Result: OK: 7348320(c7347271+d1048) usec, 5000000 (1000byte,0frags)
680427pps 5443Mb/sec (5443416000bps) errors: 0
Performances after the patch:
Result: OK: 5656067(c5655678+d388) usec, 5000000 (1000byte,0frags)
884006pps 7072Mb/sec (7072048000bps) errors: 0
Signed-off-by: David Lebrun <david.lebrun@uclouvain.be>
---
net/ipv6/seg6_iptunnel.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/ipv6/seg6_iptunnel.c b/net/ipv6/seg6_iptunnel.c
index 8558225..dda2c51 100644
--- a/net/ipv6/seg6_iptunnel.c
+++ b/net/ipv6/seg6_iptunnel.c
@@ -105,7 +105,7 @@ static int seg6_do_srh_encap(struct sk_buff *skb, struct ipv6_sr_hdr *osrh)
hdrlen = (osrh->hdrlen + 1) << 3;
tot_len = hdrlen + sizeof(*hdr);
- err = pskb_expand_head(skb, tot_len, 0, GFP_ATOMIC);
+ err = skb_cow_head(skb, tot_len);
if (unlikely(err))
return err;
@@ -156,7 +156,7 @@ static int seg6_do_srh_inline(struct sk_buff *skb, struct ipv6_sr_hdr *osrh)
hdrlen = (osrh->hdrlen + 1) << 3;
- err = pskb_expand_head(skb, hdrlen, 0, GFP_ATOMIC);
+ err = skb_cow_head(skb, hdrlen);
if (unlikely(err))
return err;
--
2.10.2
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH net-next 2/2] ipv6: sr: use dst_cache in seg6_input
2017-03-24 9:46 [PATCH net-next 0/2] Performances improvement for IPv6 Segment Routing David Lebrun
2017-03-24 9:46 ` [PATCH net-next 1/2] ipv6: sr: expand skb head only if necessary David Lebrun
@ 2017-03-24 9:46 ` David Lebrun
2017-03-24 21:48 ` [PATCH net-next 0/2] Performances improvement for IPv6 Segment Routing David Miller
2 siblings, 0 replies; 5+ messages in thread
From: David Lebrun @ 2017-03-24 9:46 UTC (permalink / raw)
To: netdev; +Cc: David Lebrun
We already use dst_cache in seg6_output, when handling locally generated
packets. We extend it in seg6_input, to also handle forwarded packets, and avoid
unnecessary fib lookups.
Performances for SRH encapsulation before the patch:
Result: OK: 5656067(c5655678+d388) usec, 5000000 (1000byte,0frags)
884006pps 7072Mb/sec (7072048000bps) errors: 0
Performances after the patch:
Result: OK: 4774543(c4774084+d459) usec, 5000000 (1000byte,0frags)
1047220pps 8377Mb/sec (8377760000bps) errors: 0
Signed-off-by: David Lebrun <david.lebrun@uclouvain.be>
---
net/ipv6/seg6_iptunnel.c | 27 ++++++++++++++++++++++++++-
1 file changed, 26 insertions(+), 1 deletion(-)
diff --git a/net/ipv6/seg6_iptunnel.c b/net/ipv6/seg6_iptunnel.c
index dda2c51..30ef1d1 100644
--- a/net/ipv6/seg6_iptunnel.c
+++ b/net/ipv6/seg6_iptunnel.c
@@ -237,6 +237,9 @@ static int seg6_do_srh(struct sk_buff *skb)
static int seg6_input(struct sk_buff *skb)
{
+ struct dst_entry *orig_dst = skb_dst(skb);
+ struct dst_entry *dst = NULL;
+ struct seg6_lwt *slwt;
int err;
err = seg6_do_srh(skb);
@@ -245,8 +248,30 @@ static int seg6_input(struct sk_buff *skb)
return err;
}
+ slwt = seg6_lwt_lwtunnel(orig_dst->lwtstate);
+
+#ifdef CONFIG_DST_CACHE
+ preempt_disable();
+ dst = dst_cache_get(&slwt->cache);
+ preempt_enable();
+#endif
+
skb_dst_drop(skb);
- ip6_route_input(skb);
+
+ if (!dst) {
+ ip6_route_input(skb);
+#ifdef CONFIG_DST_CACHE
+ dst = skb_dst(skb);
+ if (!dst->error) {
+ preempt_disable();
+ dst_cache_set_ip6(&slwt->cache, dst,
+ &ipv6_hdr(skb)->saddr);
+ preempt_enable();
+ }
+#endif
+ } else {
+ skb_dst_set(skb, dst);
+ }
return dst_input(skb);
}
--
2.10.2
^ permalink raw reply related [flat|nested] 5+ messages in thread