diff options
| author | Tom Herbert <therbert@google.com> | 2015-02-02 19:07:34 -0500 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2015-02-04 16:54:07 -0500 |
| commit | dcdc8994697faa789669c3fdaca1a8bc27a8f356 (patch) | |
| tree | a105b07298d337a0b04b114422638768c3ee9266 | |
| parent | 9a05dde59a35eee5643366d3d1e1f43fc9069adb (diff) | |
net: add skb functions to process remote checksum offload
This patch adds skb_remcsum_process and skb_gro_remcsum_process to
perform the appropriate adjustments to the skb when receiving
remote checksum offload.
Updated vxlan and gue to use these functions.
Tested: Ran TCP_RR and TCP_STREAM netperf for VXLAN and GUE, did
not see any change in performance.
Signed-off-by: Tom Herbert <therbert@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | drivers/net/vxlan.c | 18 | ||||
| -rw-r--r-- | include/linux/netdevice.h | 15 | ||||
| -rw-r--r-- | include/linux/skbuff.h | 21 | ||||
| -rw-r--r-- | net/ipv4/fou.c | 18 |
4 files changed, 40 insertions, 32 deletions
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index 31bac2a21ce3..c184717e8b28 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c | |||
| @@ -558,7 +558,6 @@ static struct vxlanhdr *vxlan_gro_remcsum(struct sk_buff *skb, | |||
| 558 | u32 data) | 558 | u32 data) |
| 559 | { | 559 | { |
| 560 | size_t start, offset, plen; | 560 | size_t start, offset, plen; |
| 561 | __wsum delta; | ||
| 562 | 561 | ||
| 563 | if (skb->remcsum_offload) | 562 | if (skb->remcsum_offload) |
| 564 | return vh; | 563 | return vh; |
| @@ -580,12 +579,7 @@ static struct vxlanhdr *vxlan_gro_remcsum(struct sk_buff *skb, | |||
| 580 | return NULL; | 579 | return NULL; |
| 581 | } | 580 | } |
| 582 | 581 | ||
| 583 | delta = remcsum_adjust((void *)vh + hdrlen, | 582 | skb_gro_remcsum_process(skb, (void *)vh + hdrlen, start, offset); |
| 584 | NAPI_GRO_CB(skb)->csum, start, offset); | ||
| 585 | |||
| 586 | /* Adjust skb->csum since we changed the packet */ | ||
| 587 | skb->csum = csum_add(skb->csum, delta); | ||
| 588 | NAPI_GRO_CB(skb)->csum = csum_add(NAPI_GRO_CB(skb)->csum, delta); | ||
| 589 | 583 | ||
| 590 | skb->remcsum_offload = 1; | 584 | skb->remcsum_offload = 1; |
| 591 | 585 | ||
| @@ -1159,7 +1153,6 @@ static struct vxlanhdr *vxlan_remcsum(struct sk_buff *skb, struct vxlanhdr *vh, | |||
| 1159 | size_t hdrlen, u32 data) | 1153 | size_t hdrlen, u32 data) |
| 1160 | { | 1154 | { |
| 1161 | size_t start, offset, plen; | 1155 | size_t start, offset, plen; |
| 1162 | __wsum delta; | ||
| 1163 | 1156 | ||
| 1164 | if (skb->remcsum_offload) { | 1157 | if (skb->remcsum_offload) { |
| 1165 | /* Already processed in GRO path */ | 1158 | /* Already processed in GRO path */ |
| @@ -1179,14 +1172,7 @@ static struct vxlanhdr *vxlan_remcsum(struct sk_buff *skb, struct vxlanhdr *vh, | |||
| 1179 | 1172 | ||
| 1180 | vh = (struct vxlanhdr *)(udp_hdr(skb) + 1); | 1173 | vh = (struct vxlanhdr *)(udp_hdr(skb) + 1); |
| 1181 | 1174 | ||
| 1182 | if (unlikely(skb->ip_summed != CHECKSUM_COMPLETE)) | 1175 | skb_remcsum_process(skb, (void *)vh + hdrlen, start, offset); |
| 1183 | __skb_checksum_complete(skb); | ||
| 1184 | |||
| 1185 | delta = remcsum_adjust((void *)vh + hdrlen, | ||
| 1186 | skb->csum, start, offset); | ||
| 1187 | |||
| 1188 | /* Adjust skb->csum since we changed the packet */ | ||
| 1189 | skb->csum = csum_add(skb->csum, delta); | ||
| 1190 | 1176 | ||
| 1191 | return vh; | 1177 | return vh; |
| 1192 | } | 1178 | } |
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 16251e96e6aa..1347ac50d2af 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h | |||
| @@ -2318,6 +2318,21 @@ do { \ | |||
| 2318 | compute_pseudo(skb, proto)); \ | 2318 | compute_pseudo(skb, proto)); \ |
| 2319 | } while (0) | 2319 | } while (0) |
| 2320 | 2320 | ||
| 2321 | static inline void skb_gro_remcsum_process(struct sk_buff *skb, void *ptr, | ||
| 2322 | int start, int offset) | ||
| 2323 | { | ||
| 2324 | __wsum delta; | ||
| 2325 | |||
| 2326 | BUG_ON(!NAPI_GRO_CB(skb)->csum_valid); | ||
| 2327 | |||
| 2328 | delta = remcsum_adjust(ptr, NAPI_GRO_CB(skb)->csum, start, offset); | ||
| 2329 | |||
| 2330 | /* Adjust skb->csum since we changed the packet */ | ||
| 2331 | skb->csum = csum_add(skb->csum, delta); | ||
| 2332 | NAPI_GRO_CB(skb)->csum = csum_add(NAPI_GRO_CB(skb)->csum, delta); | ||
| 2333 | } | ||
| 2334 | |||
| 2335 | |||
| 2321 | static inline int dev_hard_header(struct sk_buff *skb, struct net_device *dev, | 2336 | static inline int dev_hard_header(struct sk_buff *skb, struct net_device *dev, |
| 2322 | unsigned short type, | 2337 | unsigned short type, |
| 2323 | const void *daddr, const void *saddr, | 2338 | const void *daddr, const void *saddr, |
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 2748ff639144..5405dfe02572 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h | |||
| @@ -3099,6 +3099,27 @@ do { \ | |||
| 3099 | compute_pseudo(skb, proto)); \ | 3099 | compute_pseudo(skb, proto)); \ |
| 3100 | } while (0) | 3100 | } while (0) |
| 3101 | 3101 | ||
| 3102 | /* Update skbuf and packet to reflect the remote checksum offload operation. | ||
| 3103 | * When called, ptr indicates the starting point for skb->csum when | ||
| 3104 | * ip_summed is CHECKSUM_COMPLETE. If we need create checksum complete | ||
| 3105 | * here, skb_postpull_rcsum is done so skb->csum start is ptr. | ||
| 3106 | */ | ||
| 3107 | static inline void skb_remcsum_process(struct sk_buff *skb, void *ptr, | ||
| 3108 | int start, int offset) | ||
| 3109 | { | ||
| 3110 | __wsum delta; | ||
| 3111 | |||
| 3112 | if (unlikely(skb->ip_summed != CHECKSUM_COMPLETE)) { | ||
| 3113 | __skb_checksum_complete(skb); | ||
| 3114 | skb_postpull_rcsum(skb, skb->data, ptr - (void *)skb->data); | ||
| 3115 | } | ||
| 3116 | |||
| 3117 | delta = remcsum_adjust(ptr, skb->csum, start, offset); | ||
| 3118 | |||
| 3119 | /* Adjust skb->csum since we changed the packet */ | ||
| 3120 | skb->csum = csum_add(skb->csum, delta); | ||
| 3121 | } | ||
| 3122 | |||
| 3102 | #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) | 3123 | #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) |
| 3103 | void nf_conntrack_destroy(struct nf_conntrack *nfct); | 3124 | void nf_conntrack_destroy(struct nf_conntrack *nfct); |
| 3104 | static inline void nf_conntrack_put(struct nf_conntrack *nfct) | 3125 | static inline void nf_conntrack_put(struct nf_conntrack *nfct) |
diff --git a/net/ipv4/fou.c b/net/ipv4/fou.c index 3bc0cf07661c..92ddea1e6457 100644 --- a/net/ipv4/fou.c +++ b/net/ipv4/fou.c | |||
| @@ -70,7 +70,6 @@ static struct guehdr *gue_remcsum(struct sk_buff *skb, struct guehdr *guehdr, | |||
| 70 | size_t start = ntohs(pd[0]); | 70 | size_t start = ntohs(pd[0]); |
| 71 | size_t offset = ntohs(pd[1]); | 71 | size_t offset = ntohs(pd[1]); |
| 72 | size_t plen = hdrlen + max_t(size_t, offset + sizeof(u16), start); | 72 | size_t plen = hdrlen + max_t(size_t, offset + sizeof(u16), start); |
| 73 | __wsum delta; | ||
| 74 | 73 | ||
| 75 | if (skb->remcsum_offload) { | 74 | if (skb->remcsum_offload) { |
| 76 | /* Already processed in GRO path */ | 75 | /* Already processed in GRO path */ |
| @@ -82,14 +81,7 @@ static struct guehdr *gue_remcsum(struct sk_buff *skb, struct guehdr *guehdr, | |||
| 82 | return NULL; | 81 | return NULL; |
| 83 | guehdr = (struct guehdr *)&udp_hdr(skb)[1]; | 82 | guehdr = (struct guehdr *)&udp_hdr(skb)[1]; |
| 84 | 83 | ||
| 85 | if (unlikely(skb->ip_summed != CHECKSUM_COMPLETE)) | 84 | skb_remcsum_process(skb, (void *)guehdr + hdrlen, start, offset); |
| 86 | __skb_checksum_complete(skb); | ||
| 87 | |||
| 88 | delta = remcsum_adjust((void *)guehdr + hdrlen, | ||
| 89 | skb->csum, start, offset); | ||
| 90 | |||
| 91 | /* Adjust skb->csum since we changed the packet */ | ||
| 92 | skb->csum = csum_add(skb->csum, delta); | ||
| 93 | 85 | ||
| 94 | return guehdr; | 86 | return guehdr; |
| 95 | } | 87 | } |
| @@ -228,7 +220,6 @@ static struct guehdr *gue_gro_remcsum(struct sk_buff *skb, unsigned int off, | |||
| 228 | size_t start = ntohs(pd[0]); | 220 | size_t start = ntohs(pd[0]); |
| 229 | size_t offset = ntohs(pd[1]); | 221 | size_t offset = ntohs(pd[1]); |
| 230 | size_t plen = hdrlen + max_t(size_t, offset + sizeof(u16), start); | 222 | size_t plen = hdrlen + max_t(size_t, offset + sizeof(u16), start); |
| 231 | __wsum delta; | ||
| 232 | 223 | ||
| 233 | if (skb->remcsum_offload) | 224 | if (skb->remcsum_offload) |
| 234 | return guehdr; | 225 | return guehdr; |
| @@ -243,12 +234,7 @@ static struct guehdr *gue_gro_remcsum(struct sk_buff *skb, unsigned int off, | |||
| 243 | return NULL; | 234 | return NULL; |
| 244 | } | 235 | } |
| 245 | 236 | ||
| 246 | delta = remcsum_adjust((void *)guehdr + hdrlen, | 237 | skb_gro_remcsum_process(skb, (void *)guehdr + hdrlen, start, offset); |
| 247 | NAPI_GRO_CB(skb)->csum, start, offset); | ||
| 248 | |||
| 249 | /* Adjust skb->csum since we changed the packet */ | ||
| 250 | skb->csum = csum_add(skb->csum, delta); | ||
| 251 | NAPI_GRO_CB(skb)->csum = csum_add(NAPI_GRO_CB(skb)->csum, delta); | ||
| 252 | 238 | ||
| 253 | skb->remcsum_offload = 1; | 239 | skb->remcsum_offload = 1; |
| 254 | 240 | ||
