diff options
author | Alexander Duyck <alexander.h.duyck@intel.com> | 2012-05-24 04:26:29 -0400 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2012-10-23 00:13:48 -0400 |
commit | a048b40e0f9502bc75d7f9904c5399a0a87fa479 (patch) | |
tree | db65df2be656ad4bf22239dd7653fe3ee07b06b2 | |
parent | d94ce9b283736a876b2e6dec665c68e5e8b5d55e (diff) |
ixgbe: Add support for IPv6 and UDP to ixgbe_get_headlen
This change adds support for IPv6 and UDP to ixgbe_get_headlen. The
advantage to this is that we can now handle ipv4/UDP, ipv6/TCP, and
ipv6/UDP with a single memcpy instead of having to do them in multiple
pskb_may_pull calls.
A quick bit of testing shows that we increase throughput for a single
session of netperf from 8800Mpbs to about 9300Mpbs in the case of ipv6/TCP.
As such overall ipv6 performance should improve with this change.
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Tested-by: Stephen Ko <stephen.s.ko@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
-rw-r--r-- | drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index e2a6691cbd7c..3ef74f893c2e 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | |||
@@ -1244,6 +1244,7 @@ static unsigned int ixgbe_get_headlen(unsigned char *data, | |||
1244 | struct vlan_hdr *vlan; | 1244 | struct vlan_hdr *vlan; |
1245 | /* l3 headers */ | 1245 | /* l3 headers */ |
1246 | struct iphdr *ipv4; | 1246 | struct iphdr *ipv4; |
1247 | struct ipv6hdr *ipv6; | ||
1247 | } hdr; | 1248 | } hdr; |
1248 | __be16 protocol; | 1249 | __be16 protocol; |
1249 | u8 nexthdr = 0; /* default to not TCP */ | 1250 | u8 nexthdr = 0; /* default to not TCP */ |
@@ -1284,6 +1285,13 @@ static unsigned int ixgbe_get_headlen(unsigned char *data, | |||
1284 | /* record next protocol */ | 1285 | /* record next protocol */ |
1285 | nexthdr = hdr.ipv4->protocol; | 1286 | nexthdr = hdr.ipv4->protocol; |
1286 | hdr.network += hlen; | 1287 | hdr.network += hlen; |
1288 | } else if (protocol == __constant_htons(ETH_P_IPV6)) { | ||
1289 | if ((hdr.network - data) > (max_len - sizeof(struct ipv6hdr))) | ||
1290 | return max_len; | ||
1291 | |||
1292 | /* record next protocol */ | ||
1293 | nexthdr = hdr.ipv6->nexthdr; | ||
1294 | hdr.network += sizeof(struct ipv6hdr); | ||
1287 | #ifdef IXGBE_FCOE | 1295 | #ifdef IXGBE_FCOE |
1288 | } else if (protocol == __constant_htons(ETH_P_FCOE)) { | 1296 | } else if (protocol == __constant_htons(ETH_P_FCOE)) { |
1289 | if ((hdr.network - data) > (max_len - FCOE_HEADER_LEN)) | 1297 | if ((hdr.network - data) > (max_len - FCOE_HEADER_LEN)) |
@@ -1294,7 +1302,7 @@ static unsigned int ixgbe_get_headlen(unsigned char *data, | |||
1294 | return hdr.network - data; | 1302 | return hdr.network - data; |
1295 | } | 1303 | } |
1296 | 1304 | ||
1297 | /* finally sort out TCP */ | 1305 | /* finally sort out TCP/UDP */ |
1298 | if (nexthdr == IPPROTO_TCP) { | 1306 | if (nexthdr == IPPROTO_TCP) { |
1299 | if ((hdr.network - data) > (max_len - sizeof(struct tcphdr))) | 1307 | if ((hdr.network - data) > (max_len - sizeof(struct tcphdr))) |
1300 | return max_len; | 1308 | return max_len; |
@@ -1307,6 +1315,11 @@ static unsigned int ixgbe_get_headlen(unsigned char *data, | |||
1307 | return hdr.network - data; | 1315 | return hdr.network - data; |
1308 | 1316 | ||
1309 | hdr.network += hlen; | 1317 | hdr.network += hlen; |
1318 | } else if (nexthdr == IPPROTO_UDP) { | ||
1319 | if ((hdr.network - data) > (max_len - sizeof(struct udphdr))) | ||
1320 | return max_len; | ||
1321 | |||
1322 | hdr.network += sizeof(struct udphdr); | ||
1310 | } | 1323 | } |
1311 | 1324 | ||
1312 | /* | 1325 | /* |