aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/af_inet.c
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2009-01-29 09:19:50 -0500
committerDavid S. Miller <davem@davemloft.net>2009-01-29 19:33:03 -0500
commit86911732d3996a9da07914b280621450111bb6da (patch)
treee787240d5ba869ddf4d0adfc3f9c69e0372e96ef /net/ipv4/af_inet.c
parent5d0d9be8ef456afc6c3fb5f8aad06ef19b704b05 (diff)
gro: Avoid copying headers of unmerged packets
Unfortunately simplicity isn't always the best. The fraginfo interface turned out to be suboptimal. The problem was quite obvious. For every packet, we have to copy the headers from the frags structure into skb->head, even though for 99% of the packets this part is immediately thrown away after the merge. LRO didn't have this problem because it directly read the headers from the frags structure. This patch attempts to address this by creating an interface that allows GRO to access the headers in the first frag without having to copy it. Because all drivers that use frags place the headers in the first frag this optimisation should be enough. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/af_inet.c')
-rw-r--r--net/ipv4/af_inet.c10
1 files changed, 5 insertions, 5 deletions
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 743f5542d65a..d6770f295d5b 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1253,10 +1253,10 @@ static struct sk_buff **inet_gro_receive(struct sk_buff **head,
1253 int proto; 1253 int proto;
1254 int id; 1254 int id;
1255 1255
1256 if (unlikely(!pskb_may_pull(skb, sizeof(*iph)))) 1256 iph = skb_gro_header(skb, sizeof(*iph));
1257 if (unlikely(!iph))
1257 goto out; 1258 goto out;
1258 1259
1259 iph = ip_hdr(skb);
1260 proto = iph->protocol & (MAX_INET_PROTOS - 1); 1260 proto = iph->protocol & (MAX_INET_PROTOS - 1);
1261 1261
1262 rcu_read_lock(); 1262 rcu_read_lock();
@@ -1270,7 +1270,7 @@ static struct sk_buff **inet_gro_receive(struct sk_buff **head,
1270 if (unlikely(ip_fast_csum((u8 *)iph, iph->ihl))) 1270 if (unlikely(ip_fast_csum((u8 *)iph, iph->ihl)))
1271 goto out_unlock; 1271 goto out_unlock;
1272 1272
1273 flush = ntohs(iph->tot_len) != skb->len || 1273 flush = ntohs(iph->tot_len) != skb_gro_len(skb) ||
1274 iph->frag_off != htons(IP_DF); 1274 iph->frag_off != htons(IP_DF);
1275 id = ntohs(iph->id); 1275 id = ntohs(iph->id);
1276 1276
@@ -1298,8 +1298,8 @@ static struct sk_buff **inet_gro_receive(struct sk_buff **head,
1298 } 1298 }
1299 1299
1300 NAPI_GRO_CB(skb)->flush |= flush; 1300 NAPI_GRO_CB(skb)->flush |= flush;
1301 __skb_pull(skb, sizeof(*iph)); 1301 skb_gro_pull(skb, sizeof(*iph));
1302 skb_reset_transport_header(skb); 1302 skb_set_transport_header(skb, skb_gro_offset(skb));
1303 1303
1304 pp = ops->gro_receive(head, skb); 1304 pp = ops->gro_receive(head, skb);
1305 1305