diff options
author | Florian Westphal <fw@strlen.de> | 2014-09-03 09:34:42 -0400 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2014-09-12 05:24:49 -0400 |
commit | de591c783ae739f6fb41e12f3371575edcb62af0 (patch) | |
tree | ca7297ac28c2676e0a9d09739979db8822d540e5 | |
parent | 13809609610ae2ab4a7730982c3e067d8edb5a67 (diff) |
e1000: switch to napi_gro_frags api
napi_gro_frags allows skb re-use in case GRO can merge payload pages
into an skb on the GRO lists.
netperf TCP_STREAM, kvm-e1000 emulation, mtu 9k:
Size Size Size Time Throughput
bytes bytes bytes secs. 10^6bits/sec
old: 87380 16384 16384 30.00 8985.78
new: 87380 16384 16384 30.00 9907.05
Signed-off-by: Florian Westphal <fw@strlen.de>
Tested-by: Aaron Brown <aaron.f.brown@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
-rw-r--r-- | drivers/net/ethernet/intel/e1000/e1000_main.c | 49 |
1 files changed, 32 insertions, 17 deletions
diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c index 2ba640ac6b16..5f6aded512f5 100644 --- a/drivers/net/ethernet/intel/e1000/e1000_main.c +++ b/drivers/net/ethernet/intel/e1000/e1000_main.c | |||
@@ -2117,10 +2117,8 @@ static void e1000_clean_rx_ring(struct e1000_adapter *adapter, | |||
2117 | } | 2117 | } |
2118 | 2118 | ||
2119 | /* there also may be some cached data from a chained receive */ | 2119 | /* there also may be some cached data from a chained receive */ |
2120 | if (rx_ring->rx_skb_top) { | 2120 | napi_free_frags(&adapter->napi); |
2121 | dev_kfree_skb(rx_ring->rx_skb_top); | 2121 | rx_ring->rx_skb_top = NULL; |
2122 | rx_ring->rx_skb_top = NULL; | ||
2123 | } | ||
2124 | 2122 | ||
2125 | size = sizeof(struct e1000_rx_buffer) * rx_ring->count; | 2123 | size = sizeof(struct e1000_rx_buffer) * rx_ring->count; |
2126 | memset(rx_ring->buffer_info, 0, size); | 2124 | memset(rx_ring->buffer_info, 0, size); |
@@ -4133,7 +4131,6 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter, | |||
4133 | int cleaned_count = 0; | 4131 | int cleaned_count = 0; |
4134 | bool cleaned = false; | 4132 | bool cleaned = false; |
4135 | unsigned int total_rx_bytes=0, total_rx_packets=0; | 4133 | unsigned int total_rx_bytes=0, total_rx_packets=0; |
4136 | static const unsigned int bufsz = 256 - 16; /* for skb_reserve */ | ||
4137 | 4134 | ||
4138 | i = rx_ring->next_to_clean; | 4135 | i = rx_ring->next_to_clean; |
4139 | rx_desc = E1000_RX_DESC(*rx_ring, i); | 4136 | rx_desc = E1000_RX_DESC(*rx_ring, i); |
@@ -4192,7 +4189,7 @@ process_skb: | |||
4192 | /* this descriptor is only the beginning (or middle) */ | 4189 | /* this descriptor is only the beginning (or middle) */ |
4193 | if (!rxtop) { | 4190 | if (!rxtop) { |
4194 | /* this is the beginning of a chain */ | 4191 | /* this is the beginning of a chain */ |
4195 | rxtop = e1000_alloc_rx_skb(adapter, bufsz); | 4192 | rxtop = napi_get_frags(&adapter->napi); |
4196 | if (!rxtop) | 4193 | if (!rxtop) |
4197 | break; | 4194 | break; |
4198 | 4195 | ||
@@ -4221,14 +4218,17 @@ process_skb: | |||
4221 | /* no chain, got EOP, this buf is the packet | 4218 | /* no chain, got EOP, this buf is the packet |
4222 | * copybreak to save the put_page/alloc_page | 4219 | * copybreak to save the put_page/alloc_page |
4223 | */ | 4220 | */ |
4224 | skb = e1000_alloc_rx_skb(adapter, bufsz); | ||
4225 | if (!skb) | ||
4226 | break; | ||
4227 | p = buffer_info->rxbuf.page; | 4221 | p = buffer_info->rxbuf.page; |
4228 | if (length <= copybreak && | 4222 | if (length <= copybreak) { |
4229 | skb_tailroom(skb) >= length) { | ||
4230 | u8 *vaddr; | 4223 | u8 *vaddr; |
4231 | 4224 | ||
4225 | if (likely(!(netdev->features & NETIF_F_RXFCS))) | ||
4226 | length -= 4; | ||
4227 | skb = e1000_alloc_rx_skb(adapter, | ||
4228 | length); | ||
4229 | if (!skb) | ||
4230 | break; | ||
4231 | |||
4232 | vaddr = kmap_atomic(p); | 4232 | vaddr = kmap_atomic(p); |
4233 | memcpy(skb_tail_pointer(skb), vaddr, | 4233 | memcpy(skb_tail_pointer(skb), vaddr, |
4234 | length); | 4234 | length); |
@@ -4237,7 +4237,22 @@ process_skb: | |||
4237 | * buffer_info->rxbuf.page | 4237 | * buffer_info->rxbuf.page |
4238 | */ | 4238 | */ |
4239 | skb_put(skb, length); | 4239 | skb_put(skb, length); |
4240 | e1000_rx_checksum(adapter, | ||
4241 | status | rx_desc->errors << 24, | ||
4242 | le16_to_cpu(rx_desc->csum), skb); | ||
4243 | |||
4244 | total_rx_bytes += skb->len; | ||
4245 | total_rx_packets++; | ||
4246 | |||
4247 | e1000_receive_skb(adapter, status, | ||
4248 | rx_desc->special, skb); | ||
4249 | goto next_desc; | ||
4240 | } else { | 4250 | } else { |
4251 | skb = napi_get_frags(&adapter->napi); | ||
4252 | if (!skb) { | ||
4253 | adapter->alloc_rx_buff_failed++; | ||
4254 | break; | ||
4255 | } | ||
4241 | skb_fill_page_desc(skb, 0, p, 0, | 4256 | skb_fill_page_desc(skb, 0, p, 0, |
4242 | length); | 4257 | length); |
4243 | e1000_consume_page(buffer_info, skb, | 4258 | e1000_consume_page(buffer_info, skb, |
@@ -4257,14 +4272,14 @@ process_skb: | |||
4257 | pskb_trim(skb, skb->len - 4); | 4272 | pskb_trim(skb, skb->len - 4); |
4258 | total_rx_packets++; | 4273 | total_rx_packets++; |
4259 | 4274 | ||
4260 | /* eth type trans needs skb->data to point to something */ | 4275 | if (status & E1000_RXD_STAT_VP) { |
4261 | if (!pskb_may_pull(skb, ETH_HLEN)) { | 4276 | __le16 vlan = rx_desc->special; |
4262 | e_err(drv, "pskb_may_pull failed.\n"); | 4277 | u16 vid = le16_to_cpu(vlan) & E1000_RXD_SPC_VLAN_MASK; |
4263 | dev_kfree_skb(skb); | 4278 | |
4264 | goto next_desc; | 4279 | __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vid); |
4265 | } | 4280 | } |
4266 | 4281 | ||
4267 | e1000_receive_skb(adapter, status, rx_desc->special, skb); | 4282 | napi_gro_frags(&adapter->napi); |
4268 | 4283 | ||
4269 | next_desc: | 4284 | next_desc: |
4270 | rx_desc->status = 0; | 4285 | rx_desc->status = 0; |