From: Alexander Duyck <aduyck@mirantis.com>
To: intel-wired-lan@osuosl.org
Subject: [Intel-wired-lan] [next PATCH v3 05/15] i40e/i40evf: Replace header pointers with unions of pointers in Tx checksum path
Date: Sun, 24 Jan 2016 21:16:42 -0800 [thread overview]
Message-ID: <20160125051642.12004.46612.stgit@localhost.localdomain> (raw)
In-Reply-To: <20160125050602.12004.38884.stgit@localhost.localdomain>
The Tx checksum path was maintaining a set of 3 pointers and two lengths in
order to prepare the packet for being checksummed. The thing is we only
really needed 2 pointers, and the lengths that were being maintained can
easily be computed.
As such we can replace the IPv4 and IPv6 header pointers with one single
union that represents both, or a generic pointer to the start of the
network header. For the L4 headers we can do the same with TCP and a
generic pointer to the start of the transport header. The length of the
TCP header is obtained by simply multiplying doff by 4, and the network
header length can be obtained by subtracting the network header pointer
from the transport header pointer.
While I was at it I renamed l4_hdr to l4_proto to make it a bit more clear
and less likely to be confused with l4.hdr which is the transport header
pointer.
Signed-off-by: Alexander Duyck <aduyck@mirantis.com>
---
drivers/net/ethernet/intel/i40e/i40e_txrx.c | 51 +++++++++++++------------
drivers/net/ethernet/intel/i40evf/i40e_txrx.c | 52 +++++++++++++------------
2 files changed, 52 insertions(+), 51 deletions(-)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
index c84ba5d4634a..ef632fd60486 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
@@ -2392,12 +2392,21 @@ static void i40e_tx_enable_csum(struct sk_buff *skb, u32 *tx_flags,
struct i40e_ring *tx_ring,
u32 *cd_tunneling)
{
- struct ipv6hdr *this_ipv6_hdr;
- unsigned int this_tcp_hdrlen;
- struct iphdr *this_ip_hdr;
- u32 network_hdr_len;
- u8 l4_hdr = 0;
+ union {
+ struct iphdr *v4;
+ struct ipv6hdr *v6;
+ unsigned char *hdr;
+ } ip;
+ union {
+ struct tcphdr *tcp;
+ struct udphdr *udp;
+ unsigned char *hdr;
+ } l4;
u32 l4_tunnel = 0;
+ u8 l4_proto = 0;
+
+ ip.hdr = skb_network_header(skb);
+ l4.hdr = skb_transport_header(skb);
if (skb->encapsulation) {
switch (ip_hdr(skb)->protocol) {
@@ -2412,10 +2421,10 @@ static void i40e_tx_enable_csum(struct sk_buff *skb, u32 *tx_flags,
default:
return;
}
- network_hdr_len = skb_inner_network_header_len(skb);
- this_ip_hdr = inner_ip_hdr(skb);
- this_ipv6_hdr = inner_ipv6_hdr(skb);
- this_tcp_hdrlen = inner_tcp_hdrlen(skb);
+
+ /* switch L4 header pointer from outer to inner */
+ ip.hdr = skb_inner_network_header(skb);
+ l4.hdr = skb_inner_transport_header(skb);
if (*tx_flags & I40E_TX_FLAGS_IPV4) {
if (*tx_flags & I40E_TX_FLAGS_TSO) {
@@ -2435,20 +2444,15 @@ static void i40e_tx_enable_csum(struct sk_buff *skb, u32 *tx_flags,
((skb_inner_network_offset(skb) -
skb_transport_offset(skb)) >> 1) <<
I40E_TXD_CTX_QW0_NATLEN_SHIFT;
- if (this_ip_hdr->version == 6) {
+ if (ip.v6->version == 6) {
*tx_flags &= ~I40E_TX_FLAGS_IPV4;
*tx_flags |= I40E_TX_FLAGS_IPV6;
}
- } else {
- network_hdr_len = skb_network_header_len(skb);
- this_ip_hdr = ip_hdr(skb);
- this_ipv6_hdr = ipv6_hdr(skb);
- this_tcp_hdrlen = tcp_hdrlen(skb);
}
/* Enable IP checksum offloads */
if (*tx_flags & I40E_TX_FLAGS_IPV4) {
- l4_hdr = this_ip_hdr->protocol;
+ l4_proto = ip.v4->protocol;
/* the stack computes the IP header already, the only time we
* need the hardware to recompute it is in the case of TSO.
*/
@@ -2457,26 +2461,23 @@ static void i40e_tx_enable_csum(struct sk_buff *skb, u32 *tx_flags,
} else {
*td_cmd |= I40E_TX_DESC_CMD_IIPT_IPV4;
}
- /* Now set the td_offset for IP header length */
- *td_offset = (network_hdr_len >> 2) <<
- I40E_TX_DESC_LENGTH_IPLEN_SHIFT;
} else if (*tx_flags & I40E_TX_FLAGS_IPV6) {
- l4_hdr = this_ipv6_hdr->nexthdr;
+ l4_proto = ip.v6->nexthdr;
*td_cmd |= I40E_TX_DESC_CMD_IIPT_IPV6;
- /* Now set the td_offset for IP header length */
- *td_offset = (network_hdr_len >> 2) <<
- I40E_TX_DESC_LENGTH_IPLEN_SHIFT;
}
+
+ /* Now set the td_offset for IP header length */
+ *td_offset = ((l4.hdr - ip.hdr) / 4) << I40E_TX_DESC_LENGTH_IPLEN_SHIFT;
/* words in MACLEN + dwords in IPLEN + dwords in L4Len */
*td_offset |= (skb_network_offset(skb) >> 1) <<
I40E_TX_DESC_LENGTH_MACLEN_SHIFT;
/* Enable L4 checksum offloads */
- switch (l4_hdr) {
+ switch (l4_proto) {
case IPPROTO_TCP:
/* enable checksum offloads */
*td_cmd |= I40E_TX_DESC_CMD_L4T_EOFT_TCP;
- *td_offset |= (this_tcp_hdrlen >> 2) <<
+ *td_offset |= l4.tcp->doff <<
I40E_TX_DESC_LENGTH_L4_FC_LEN_SHIFT;
break;
case IPPROTO_SCTP:
diff --git a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c
index 1b2788093425..b1c8ada663aa 100644
--- a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c
+++ b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c
@@ -1609,12 +1609,21 @@ static void i40e_tx_enable_csum(struct sk_buff *skb, u32 *tx_flags,
struct i40e_ring *tx_ring,
u32 *cd_tunneling)
{
- struct ipv6hdr *this_ipv6_hdr;
- unsigned int this_tcp_hdrlen;
- struct iphdr *this_ip_hdr;
- u32 network_hdr_len;
- u8 l4_hdr = 0;
+ union {
+ struct iphdr *v4;
+ struct ipv6hdr *v6;
+ unsigned char *hdr;
+ } ip;
+ union {
+ struct tcphdr *tcp;
+ struct udphdr *udp;
+ unsigned char *hdr;
+ } l4;
u32 l4_tunnel = 0;
+ u8 l4_proto = 0;
+
+ ip.hdr = skb_network_header(skb);
+ l4.hdr = skb_transport_header(skb);
if (skb->encapsulation) {
switch (ip_hdr(skb)->protocol) {
@@ -1625,10 +1634,10 @@ static void i40e_tx_enable_csum(struct sk_buff *skb, u32 *tx_flags,
default:
return;
}
- network_hdr_len = skb_inner_network_header_len(skb);
- this_ip_hdr = inner_ip_hdr(skb);
- this_ipv6_hdr = inner_ipv6_hdr(skb);
- this_tcp_hdrlen = inner_tcp_hdrlen(skb);
+
+ /* switch L4 header pointer from outer to inner */
+ ip.hdr = skb_inner_network_header(skb);
+ l4.hdr = skb_inner_transport_header(skb);
if (*tx_flags & I40E_TX_FLAGS_IPV4) {
if (*tx_flags & I40E_TX_FLAGS_TSO) {
@@ -1648,21 +1657,15 @@ static void i40e_tx_enable_csum(struct sk_buff *skb, u32 *tx_flags,
((skb_inner_network_offset(skb) -
skb_transport_offset(skb)) >> 1) <<
I40E_TXD_CTX_QW0_NATLEN_SHIFT;
- if (this_ip_hdr->version == 6) {
+ if (ip.v6->version == 6) {
*tx_flags &= ~I40E_TX_FLAGS_IPV4;
*tx_flags |= I40E_TX_FLAGS_IPV6;
}
-
- } else {
- network_hdr_len = skb_network_header_len(skb);
- this_ip_hdr = ip_hdr(skb);
- this_ipv6_hdr = ipv6_hdr(skb);
- this_tcp_hdrlen = tcp_hdrlen(skb);
}
/* Enable IP checksum offloads */
if (*tx_flags & I40E_TX_FLAGS_IPV4) {
- l4_hdr = this_ip_hdr->protocol;
+ l4_proto = ip.v4->protocol;
/* the stack computes the IP header already, the only time we
* need the hardware to recompute it is in the case of TSO.
*/
@@ -1671,26 +1674,23 @@ static void i40e_tx_enable_csum(struct sk_buff *skb, u32 *tx_flags,
} else {
*td_cmd |= I40E_TX_DESC_CMD_IIPT_IPV4;
}
- /* Now set the td_offset for IP header length */
- *td_offset = (network_hdr_len >> 2) <<
- I40E_TX_DESC_LENGTH_IPLEN_SHIFT;
} else if (*tx_flags & I40E_TX_FLAGS_IPV6) {
- l4_hdr = this_ipv6_hdr->nexthdr;
+ l4_proto = ip.v6->nexthdr;
*td_cmd |= I40E_TX_DESC_CMD_IIPT_IPV6;
- /* Now set the td_offset for IP header length */
- *td_offset = (network_hdr_len >> 2) <<
- I40E_TX_DESC_LENGTH_IPLEN_SHIFT;
}
+
+ /* Now set the td_offset for IP header length */
+ *td_offset = ((l4.hdr - ip.hdr) / 4) << I40E_TX_DESC_LENGTH_IPLEN_SHIFT;
/* words in MACLEN + dwords in IPLEN + dwords in L4Len */
*td_offset |= (skb_network_offset(skb) >> 1) <<
I40E_TX_DESC_LENGTH_MACLEN_SHIFT;
/* Enable L4 checksum offloads */
- switch (l4_hdr) {
+ switch (l4_proto) {
case IPPROTO_TCP:
/* enable checksum offloads */
*td_cmd |= I40E_TX_DESC_CMD_L4T_EOFT_TCP;
- *td_offset |= (this_tcp_hdrlen >> 2) <<
+ *td_offset |= l4.tcp->doff <<
I40E_TX_DESC_LENGTH_L4_FC_LEN_SHIFT;
break;
case IPPROTO_SCTP:
next prev parent reply other threads:[~2016-01-25 5:16 UTC|newest]
Thread overview: 39+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-01-25 5:16 [Intel-wired-lan] [next PATCH v3 00/15] TSO and checksum fixes for i40e Alexander Duyck
2016-01-25 5:16 ` [Intel-wired-lan] [next PATCH v3 01/15] i40e/i40evf: Drop outer checksum offload that was not requested Alexander Duyck
2016-01-27 16:00 ` Bowers, AndrewX
2016-01-25 5:16 ` [Intel-wired-lan] [next PATCH v3 02/15] i40e/i40evf: Use u64 values instead of casting them in TSO function Alexander Duyck
2016-01-27 16:03 ` Bowers, AndrewX
2016-01-25 5:16 ` [Intel-wired-lan] [next PATCH v3 03/15] i40e/i40evf: Factor out L4 header and checksum from L3 bits in TSO path Alexander Duyck
2016-01-27 16:09 ` Bowers, AndrewX
2016-01-25 5:16 ` [Intel-wired-lan] [next PATCH v3 04/15] i40e/i40evf: Consolidate all header changes into TSO function Alexander Duyck
2016-01-27 16:14 ` Bowers, AndrewX
2016-01-25 5:16 ` Alexander Duyck [this message]
2016-01-27 16:27 ` [Intel-wired-lan] [next PATCH v3 05/15] i40e/i40evf: Replace header pointers with unions of pointers in Tx checksum path Bowers, AndrewX
2016-01-25 5:16 ` [Intel-wired-lan] [next PATCH v3 06/15] i40e/i40evf: Add support for IPv4 encapsulated in IPv6 Alexander Duyck
2016-01-27 18:04 ` Bowers, AndrewX
2016-01-25 5:16 ` [Intel-wired-lan] [next PATCH v3 07/15] i40e/i40evf: Handle IPv6 extension headers in checksum offload Alexander Duyck
2016-01-27 18:05 ` Bowers, AndrewX
2016-01-25 5:17 ` [Intel-wired-lan] [next PATCH v3 08/15] i40e/i40evf: Do not write to descriptor unless we complete Alexander Duyck
2016-01-27 18:07 ` Bowers, AndrewX
2016-01-25 5:17 ` [Intel-wired-lan] [next PATCH v3 09/15] i40e/i40evf: Add exception handling for Tx checksum Alexander Duyck
2016-01-27 18:08 ` Bowers, AndrewX
2016-01-25 5:17 ` [Intel-wired-lan] [next PATCH v3 10/15] i40e/i40evf: Clean-up Rx packet checksum handling Alexander Duyck
2016-01-27 18:09 ` Bowers, AndrewX
2016-01-25 5:17 ` [Intel-wired-lan] [next PATCH v3 11/15] i40e/i40evf: Enable support for SKB_GSO_UDP_TUNNEL_CSUM Alexander Duyck
2016-01-27 18:17 ` Bowers, AndrewX
2016-02-02 22:49 ` Jesse Brandeburg
2016-02-02 23:10 ` Jesse Brandeburg
2016-02-02 23:18 ` Jesse Brandeburg
2016-02-03 0:06 ` Alexander Duyck
2016-01-25 5:17 ` [Intel-wired-lan] [next PATCH v3 12/15] i40e: Fix ATR in relation to tunnels Alexander Duyck
2016-01-25 19:27 ` Patil, Kiran
2016-01-25 22:21 ` Alexander Duyck
2016-01-26 0:16 ` Patil, Kiran
2016-01-27 18:18 ` Bowers, AndrewX
2016-01-25 5:17 ` [Intel-wired-lan] [next PATCH v3 13/15] i40e: Do not drop support for IPv6 VXLAN or GENEVE tunnels Alexander Duyck
2016-01-27 18:26 ` Bowers, AndrewX
2016-01-25 5:17 ` [Intel-wired-lan] [next PATCH v3 14/15] i40e: Update feature flags to reflect newly enabled features Alexander Duyck
2016-01-27 18:44 ` Bowers, AndrewX
2016-01-25 5:17 ` [Intel-wired-lan] [next PATCH v3 15/15] i40evf: " Alexander Duyck
2016-01-25 19:43 ` Singhai, Anjali
2016-01-27 18:45 ` Bowers, AndrewX
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20160125051642.12004.46612.stgit@localhost.localdomain \
--to=aduyck@mirantis.com \
--cc=intel-wired-lan@osuosl.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.