net: gro: skb_gro_header helper function
Subsystems (4)
PATCH v2 1/1 net: gro: skb_gro_header helper function
Introduce a simple helper function to replace a common pattern. When accessing the GRO header, we fetch the pointer from frag0, then test its validity and fetch it from the skb when necessary.
This leads to the patternskb_gro_header_fast -> skb_gro_header_hard -> skb_gro_header_slow recurring many times throughout GRO code.
This patch replaces these patterns with a single inlined function call, improving code readability.
--- drivers/net/geneve.c | 9 +++------ drivers/net/vxlan/vxlan_core.c | 9 +++------ include/net/gro.h | 33 ++++++++++++++++++--------------- net/8021q/vlan_core.c | 9 +++------ net/ethernet/eth.c | 9 +++------ net/ipv4/af_inet.c | 9 +++------ net/ipv4/fou.c | 9 +++------ net/ipv4/gre_offload.c | 9 +++------ net/ipv4/tcp_offload.c | 9 +++------ net/ipv6/ip6_offload.c | 9 +++------ 10 files changed, 45 insertions(+), 69 deletions(-)
drivers/net/geneve.c +3 -6
@@ -503,12 +503,9 @@ static struct sk_buff *geneve_gro_receive(struct sock *sk, off_gnv =skb_gro_offset (skb); hlen = off_gnv +sizeof (*gh); - gh =skb_gro_header_fast (skb, off_gnv); -if (skb_gro_header_hard (skb, hlen)) { - gh =skb_gro_header_slow (skb, hlen, off_gnv); -if (unlikely (!gh)) - goto out; - } + gh =skb_gro_header (skb, hlen, off_gnv); +if (unlikely (!gh)) + goto out;if (gh->ver !=GENEVE_VER || gh->oam) goto out;
drivers/net/vxlan/vxlan_core.c +3 -6
@@ -713,12 +713,9 @@ static struct sk_buff *vxlan_gro_receive(struct sock *sk, off_vx =skb_gro_offset (skb); hlen = off_vx +sizeof (*vh); - vh =skb_gro_header_fast (skb, off_vx); -if (skb_gro_header_hard (skb, hlen)) { - vh =skb_gro_header_slow (skb, hlen, off_vx); -if (unlikely (!vh)) - goto out; - } + vh =skb_gro_header (skb, hlen, off_vx); +if (unlikely (!vh)) + goto out;skb_gro_postpull_rcsum (skb, vh,sizeof (struct vxlanhdr ));
include/net/gro.h +18 -15
@@ -160,6 +160,17 @@ static inline void *skb_gro_header_slow(struct sk_buff *skb, unsigned int hlen,return skb->data + offset; } +static inline void *skb_gro_header (struct sk_buff *skb, +unsigned int hlen,unsigned int offset) +{ +void *ptr; + + ptr =skb_gro_header_fast (skb, offset); +if (skb_gro_header_hard (skb, hlen)) + ptr =skb_gro_header_slow (skb, hlen, offset); +return ptr; +} +static inline void *skb_gro_network_header (struct sk_buff *skb) { return (NAPI_GRO_CB(skb)->frag0 ?: skb->data) +
@@ -301,12 +312,9 @@ static inline void *skb_gro_remcsum_process(struct sk_buff *skb, void *ptr,return ptr; } - ptr =skb_gro_header_fast (skb, off); -if (skb_gro_header_hard (skb, off + plen)) { - ptr =skb_gro_header_slow (skb, off + plen, off); -if (!ptr) -return NULL ; - } + ptr =skb_gro_header (skb, off + plen, off); +if (!ptr) +return NULL ; delta =remcsum_adjust (ptr + hdrlen,NAPI_GRO_CB (skb)->csum, start, offset);
@@ -329,12 +337,9 @@ static inline void skb_gro_remcsum_cleanup(struct sk_buff *skb,if (!grc->delta)return ; - ptr =skb_gro_header_fast (skb, grc->offset); -if (skb_gro_header_hard (skb, grc->offset +sizeof (u16))) { - ptr =skb_gro_header_slow (skb, plen, grc->offset); -if (!ptr) -return ; - } + ptr =skb_gro_header (skb, plen, grc->offset); +if (!ptr) +return ;remcsum_unadjust ((__sum16 *)ptr, grc->delta); }
@@ -405,9 +410,7 @@ static inline struct udphdr *udp_gro_udphdr(struct sk_buff *skb) off =skb_gro_offset (skb); hlen = off +sizeof (*uh); - uh =skb_gro_header_fast (skb, off); -if (skb_gro_header_hard (skb, hlen)) - uh =skb_gro_header_slow (skb, hlen, off); + uh =skb_gro_header (skb, hlen, off);return uh; }
net/8021q/vlan_core.c +3 -6
@@ -467,12 +467,9 @@ static struct sk_buff *vlan_gro_receive(struct list_head *head, off_vlan =skb_gro_offset (skb); hlen = off_vlan +sizeof (*vhdr); - vhdr =skb_gro_header_fast (skb, off_vlan); -if (skb_gro_header_hard (skb, hlen)) { - vhdr =skb_gro_header_slow (skb, hlen, off_vlan); -if (unlikely (!vhdr)) - goto out; - } + vhdr =skb_gro_header (skb, hlen, off_vlan); +if (unlikely (!vhdr)) + goto out; type = vhdr->h_vlan_encapsulated_proto;
net/ethernet/eth.c +3 -6
@@ -414,12 +414,9 @@ struct sk_buff *eth_gro_receive(struct list_head *head, struct sk_buff *skb) off_eth =skb_gro_offset (skb); hlen = off_eth +sizeof (*eh); - eh =skb_gro_header_fast (skb, off_eth); -if (skb_gro_header_hard (skb, hlen)) { - eh =skb_gro_header_slow (skb, hlen, off_eth); -if (unlikely (!eh)) - goto out; - } + eh =skb_gro_header (skb, hlen, off_eth); +if (unlikely (!eh)) + goto out; flush =0 ;
net/ipv4/af_inet.c +3 -6
@@ -1448,12 +1448,9 @@ struct sk_buff *inet_gro_receive(struct list_head *head, struct sk_buff *skb) off =skb_gro_offset (skb); hlen = off +sizeof (*iph); - iph =skb_gro_header_fast (skb, off); -if (skb_gro_header_hard (skb, hlen)) { - iph =skb_gro_header_slow (skb, hlen, off); -if (unlikely (!iph)) - goto out; - } + iph =skb_gro_header (skb, hlen, off); +if (unlikely (!iph)) + goto out; proto = iph->protocol;
net/ipv4/fou.c +3 -6
@@ -323,12 +323,9 @@ static struct sk_buff *gue_gro_receive(struct sock *sk, off =skb_gro_offset (skb); len = off +sizeof (*guehdr); - guehdr =skb_gro_header_fast (skb, off); -if (skb_gro_header_hard (skb, len)) { - guehdr =skb_gro_header_slow (skb, len, off); -if (unlikely (!guehdr)) - goto out; - } + guehdr =skb_gro_header (skb, len, off); +if (unlikely (!guehdr)) + goto out;switch (guehdr->version) {case 0 :
net/ipv4/gre_offload.c +3 -6
@@ -137,12 +137,9 @@ static struct sk_buff *gre_gro_receive(struct list_head *head, off =skb_gro_offset (skb); hlen = off +sizeof (*greh); - greh =skb_gro_header_fast (skb, off); -if (skb_gro_header_hard (skb, hlen)) { - greh =skb_gro_header_slow (skb, hlen, off); -if (unlikely (!greh)) - goto out; - } + greh =skb_gro_header (skb, hlen, off); +if (unlikely (!greh)) + goto out;/* Only support version 0 and K (key), C (csum) flags. Note that * although the support for the S (seq#) flag can be added easily
net/ipv4/tcp_offload.c +3 -6
@@ -195,12 +195,9 @@ struct sk_buff *tcp_gro_receive(struct list_head *head, struct sk_buff *skb) off =skb_gro_offset (skb); hlen = off +sizeof (*th); - th =skb_gro_header_fast (skb, off); -if (skb_gro_header_hard (skb, hlen)) { - th =skb_gro_header_slow (skb, hlen, off); -if (unlikely (!th)) - goto out; - } + th =skb_gro_header (skb, hlen, off); +if (unlikely (!th)) + goto out; thlen = th->doff *4 ;if (thlen <sizeof (*th))
net/ipv6/ip6_offload.c +3 -6
@@ -219,12 +219,9 @@ INDIRECT_CALLABLE_SCOPE struct sk_buff *ipv6_gro_receive(struct list_head *head, off =skb_gro_offset (skb); hlen = off +sizeof (*iph); - iph =skb_gro_header_fast (skb, off); -if (skb_gro_header_hard (skb, hlen)) { - iph =skb_gro_header_slow (skb, hlen, off); -if (unlikely (!iph)) - goto out; - } + iph =skb_gro_header_slow (skb, hlen, off); +if (unlikely (!iph)) + goto out;skb_set_network_header (skb, off);skb_gro_pull (skb,sizeof (*iph));
Signature · 1 line
2.36.1
Quoted 5 lines · Richard Gobert
Introduce a simple helper function to replace a common pattern. When accessing the GRO header, we fetch the pointer from frag0, then test its validity and fetch it from the skb when necessary.
Quoted 8 lines
This leads to the pattern
skb_gro_header_fast->skb_gro_header_hard->skb_gro_header_slowrecurring many times throughout GRO code.This patch replaces these patterns with a single inlined function call, improving code readability.
Signed-off-by Richard Gobert <[email protected]>
Please next time, add what has changed between V1 and V2, after the --- marker.
Thanks.
Quoted 261 lines
--- drivers/net/geneve.c | 9 +++------ drivers/net/vxlan/vxlan_core.c | 9 +++------ include/net/gro.h | 33 ++++++++++++++++++--------------- net/8021q/vlan_core.c | 9 +++------ net/ethernet/eth.c | 9 +++------ net/ipv4/af_inet.c | 9 +++------ net/ipv4/fou.c | 9 +++------ net/ipv4/gre_offload.c | 9 +++------ net/ipv4/tcp_offload.c | 9 +++------ net/ipv6/ip6_offload.c | 9 +++------ 10 files changed, 45 insertions(+), 69 deletions(-)drivers/net/geneve.c +3
-6@@ -503,12 +503,9 @@ static struct sk_buff *geneve_gro_receive(struct sock *sk, off_gnv =skb_gro_offset (skb); hlen = off_gnv +sizeof (*gh); - gh =skb_gro_header_fast (skb, off_gnv); -if (skb_gro_header_hard (skb, hlen)) { - gh =skb_gro_header_slow (skb, hlen, off_gnv); -if (unlikely (!gh)) - goto out; - } + gh =skb_gro_header (skb, hlen, off_gnv); +if (unlikely (!gh)) + goto out;if (gh->ver !=GENEVE_VER || gh->oam) goto out;drivers/net/vxlan/vxlan_core.c +3
-6@@ -713,12 +713,9 @@ static struct sk_buff *vxlan_gro_receive(struct sock *sk, off_vx =skb_gro_offset (skb); hlen = off_vx +sizeof (*vh); - vh =skb_gro_header_fast (skb, off_vx); -if (skb_gro_header_hard (skb, hlen)) { - vh =skb_gro_header_slow (skb, hlen, off_vx); -if (unlikely (!vh)) - goto out; - } + vh =skb_gro_header (skb, hlen, off_vx); +if (unlikely (!vh)) + goto out;skb_gro_postpull_rcsum (skb, vh,sizeof (struct vxlanhdr ));include/net/gro.h +18
-15@@ -160,6 +160,17 @@ static inline void *skb_gro_header_slow(struct sk_buff *skb, unsigned int hlen,return skb->data + offset; } +static inline void *skb_gro_header (struct sk_buff *skb, +unsigned int hlen,unsigned int offset) +{ +void *ptr; + + ptr =skb_gro_header_fast (skb, offset); +if (skb_gro_header_hard (skb, hlen)) + ptr =skb_gro_header_slow (skb, hlen, offset); +return ptr; +} +static inline void *skb_gro_network_header (struct sk_buff *skb) { return (NAPI_GRO_CB(skb)->frag0 ?: skb->data) +@@ -301,12 +312,9 @@ static inline void *skb_gro_remcsum_process(struct sk_buff *skb, void *ptr,return ptr; } - ptr =skb_gro_header_fast (skb, off); -if (skb_gro_header_hard (skb, off + plen)) { - ptr =skb_gro_header_slow (skb, off + plen, off); -if (!ptr) -return NULL ; - } + ptr =skb_gro_header (skb, off + plen, off); +if (!ptr) +return NULL ; delta =remcsum_adjust (ptr + hdrlen,NAPI_GRO_CB (skb)->csum, start, offset);@@ -329,12 +337,9 @@ static inline void skb_gro_remcsum_cleanup(struct sk_buff *skb,if (!grc->delta)return ; - ptr =skb_gro_header_fast (skb, grc->offset); -if (skb_gro_header_hard (skb, grc->offset +sizeof (u16))) { - ptr =skb_gro_header_slow (skb, plen, grc->offset); -if (!ptr) -return ; - } + ptr =skb_gro_header (skb, plen, grc->offset); +if (!ptr) +return ;remcsum_unadjust ((__sum16 *)ptr, grc->delta); }@@ -405,9 +410,7 @@ static inline struct udphdr *udp_gro_udphdr(struct sk_buff *skb) off =skb_gro_offset (skb); hlen = off +sizeof (*uh); - uh =skb_gro_header_fast (skb, off); -if (skb_gro_header_hard (skb, hlen)) - uh =skb_gro_header_slow (skb, hlen, off); + uh =skb_gro_header (skb, hlen, off);return uh; }net/8021q/vlan_core.c +3
-6@@ -467,12 +467,9 @@ static struct sk_buff *vlan_gro_receive(struct list_head *head, off_vlan =skb_gro_offset (skb); hlen = off_vlan +sizeof (*vhdr); - vhdr =skb_gro_header_fast (skb, off_vlan); -if (skb_gro_header_hard (skb, hlen)) { - vhdr =skb_gro_header_slow (skb, hlen, off_vlan); -if (unlikely (!vhdr)) - goto out; - } + vhdr =skb_gro_header (skb, hlen, off_vlan); +if (unlikely (!vhdr)) + goto out; type = vhdr->h_vlan_encapsulated_proto;net/ethernet/eth.c +3
-6@@ -414,12 +414,9 @@ struct sk_buff *eth_gro_receive(struct list_head *head, struct sk_buff *skb) off_eth =skb_gro_offset (skb); hlen = off_eth +sizeof (*eh); - eh =skb_gro_header_fast (skb, off_eth); -if (skb_gro_header_hard (skb, hlen)) { - eh =skb_gro_header_slow (skb, hlen, off_eth); -if (unlikely (!eh)) - goto out; - } + eh =skb_gro_header (skb, hlen, off_eth); +if (unlikely (!eh)) + goto out; flush =0 ;net/ipv4/af_inet.c +3
-6@@ -1448,12 +1448,9 @@ struct sk_buff *inet_gro_receive(struct list_head *head, struct sk_buff *skb) off =skb_gro_offset (skb); hlen = off +sizeof (*iph); - iph =skb_gro_header_fast (skb, off); -if (skb_gro_header_hard (skb, hlen)) { - iph =skb_gro_header_slow (skb, hlen, off); -if (unlikely (!iph)) - goto out; - } + iph =skb_gro_header (skb, hlen, off); +if (unlikely (!iph)) + goto out; proto = iph->protocol;net/ipv4/fou.c +3
-6@@ -323,12 +323,9 @@ static struct sk_buff *gue_gro_receive(struct sock *sk, off =skb_gro_offset (skb); len = off +sizeof (*guehdr); - guehdr =skb_gro_header_fast (skb, off); -if (skb_gro_header_hard (skb, len)) { - guehdr =skb_gro_header_slow (skb, len, off); -if (unlikely (!guehdr)) - goto out; - } + guehdr =skb_gro_header (skb, len, off); +if (unlikely (!guehdr)) + goto out;switch (guehdr->version) {case 0 :net/ipv4/gre_offload.c +3
-6@@ -137,12 +137,9 @@ static struct sk_buff *gre_gro_receive(struct list_head *head, off =skb_gro_offset (skb); hlen = off +sizeof (*greh); - greh =skb_gro_header_fast (skb, off); -if (skb_gro_header_hard (skb, hlen)) { - greh =skb_gro_header_slow (skb, hlen, off); -if (unlikely (!greh)) - goto out; - } + greh =skb_gro_header (skb, hlen, off); +if (unlikely (!greh)) + goto out;/* Only support version 0 and K (key), C (csum) flags. Note that * although the support for the S (seq#) flag can be added easily net/ipv4/tcp_offload.c +3
-6@@ -195,12 +195,9 @@ struct sk_buff *tcp_gro_receive(struct list_head *head, struct sk_buff *skb) off =skb_gro_offset (skb); hlen = off +sizeof (*th); - th =skb_gro_header_fast (skb, off); -if (skb_gro_header_hard (skb, hlen)) { - th =skb_gro_header_slow (skb, hlen, off); -if (unlikely (!th)) - goto out; - } + th =skb_gro_header (skb, hlen, off); +if (unlikely (!th)) + goto out; thlen = th->doff *4 ;if (thlen <sizeof (*th))net/ipv6/ip6_offload.c +3
-7@@ -219,12 +219,9 @@ INDIRECT_CALLABLE_SCOPE struct sk_buff *ipv6_gro_receive(struct list_head *head, off =skb_gro_offset (skb); hlen = off +sizeof (*iph); - iph =skb_gro_header_fast (skb, off); -if (skb_gro_header_hard (skb, hlen)) { - iph =skb_gro_header_slow (skb, hlen, off); -if (unlikely (!iph)) - goto out; - } + iph =skb_gro_header_slow (skb, hlen, off); +if (unlikely (!iph)) + goto out;skb_set_network_header (skb, off);skb_gro_pull (skb,sizeof (*iph)); --2.36.1
This patch was applied to netdev/net-next.git (master) by Paolo Abeni <[email protected]>:
Hello:
This patch was applied to netdev/net-next.git (master) by Paolo Abeni <[email protected]>:
Quoted 9 lines · On Tue, 23 Aug 2022 09:10:49 +0200 you wrote:
Introduce a simple helper function to replace a common pattern. When accessing the GRO header, we fetch the pointer from frag0, then test its validity and fetch it from the skb when necessary.
This leads to the pattern
skb_gro_header_fast->skb_gro_header_hard->skb_gro_header_slowrecurring many times throughout GRO code.[...]
Here is the summary with links:
- [V2] net: gro: skb_gro_header helper function
https://git.kernel.org/netdev/net-next/c/35ffb6654729
You are awesome, thank you!
Signature · 2 lines
Deet-doot-dot, I am a bot. https://korg.docs.kernel.org/patchwork/pwbot.html