gro: New frags interface to avoid copying shinfo

It turns out that copying a 16-byte area at ~800k times a second
can be really expensive :) This patch redesigns the frags GRO
interface to avoid copying that area twice.

The two disciples of the frags interface have been converted.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Herbert Xu
2009-04-16 02:02:07 -07:00
committed by David S. Miller
parent 861ab44059
commit 76620aafd6
7 changed files with 102 additions and 94 deletions

View File

@@ -450,17 +450,27 @@ static void efx_rx_packet_lro(struct efx_channel *channel,
/* Pass the skb/page into the LRO engine */
if (rx_buf->page) {
struct napi_gro_fraginfo info;
struct sk_buff *skb = napi_get_frags(napi);
info.frags[0].page = rx_buf->page;
info.frags[0].page_offset = efx_rx_buf_offset(rx_buf);
info.frags[0].size = rx_buf->len;
info.nr_frags = 1;
info.ip_summed = CHECKSUM_UNNECESSARY;
info.len = rx_buf->len;
if (!skb) {
put_page(rx_buf->page);
goto out;
}
napi_gro_frags(napi, &info);
skb_shinfo(skb)->frags[0].page = rx_buf->page;
skb_shinfo(skb)->frags[0].page_offset =
efx_rx_buf_offset(rx_buf);
skb_shinfo(skb)->frags[0].size = rx_buf->len;
skb_shinfo(skb)->nr_frags = 1;
skb->len = rx_buf->len;
skb->data_len = rx_buf->len;
skb->truesize += rx_buf->len;
skb->ip_summed = CHECKSUM_UNNECESSARY;
napi_gro_frags(napi);
out:
EFX_BUG_ON_PARANOID(rx_buf->skb);
rx_buf->page = NULL;
} else {