aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/af_inet.c
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2012-08-05 18:34:50 -0400
committerDavid S. Miller <davem@davemloft.net>2012-08-06 16:40:47 -0400
commita9e050f4e7f9d36afe0dcc0bddba864ee442715e (patch)
treeefef227190c746df2b974b868d4ecc40a06bd60b /net/ipv4/af_inet.c
parent14a196807482e6fc74f15fc03176d5c08880588f (diff)
net: tcp: GRO should be ECN friendly
While doing TCP ECN tests, I discovered GRO was reordering packets if it receives one packet with CE set, while previous packets in same NAPI run have ECT(0) for the same flow : 09:25:25.857620 IP (tos 0x2,ECT(0), ttl 64, id 27893, offset 0, flags [DF], proto TCP (6), length 4396) 172.30.42.19.54550 > 172.30.42.13.44139: Flags [.], seq 233801:238145, ack 1, win 115, options [nop,nop,TS val 3397779 ecr 1990627], length 4344 09:25:25.857626 IP (tos 0x3,CE, ttl 64, id 27892, offset 0, flags [DF], proto TCP (6), length 1500) 172.30.42.19.54550 > 172.30.42.13.44139: Flags [.], seq 232353:233801, ack 1, win 115, options [nop,nop,TS val 3397779 ecr 1990627], length 1448 09:25:25.857638 IP (tos 0x0, ttl 64, id 34581, offset 0, flags [DF], proto TCP (6), length 64) 172.30.42.13.44139 > 172.30.42.19.54550: Flags [.], cksum 0xac8f (incorrect -> 0xca69), ack 232353, win 1271, options [nop,nop,TS val 1990627 ecr 3397779,nop,nop,sack 1 {233801:238145}], length 0 We have two problems here : 1) GRO reorders packets If NIC gave packet1, then packet2, which happen to be from "different flows" GRO feeds stack with packet2, then packet1. I have yet to understand how to solve this problem. 2) GRO is not ECN friendly Delivering packets out of order makes TCP stack not as fast as it could be. In this patch I suggest we make the tos test not part of the 'same_flow' determination, but part of the 'should flush' logic Signed-off-by: Eric Dumazet <edumazet@google.com> Cc: Herbert Xu <herbert@gondor.apana.org.au> Acked-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.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index fe4582ca969a..6681ccf5c3ee 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1364,7 +1364,7 @@ static struct sk_buff **inet_gro_receive(struct sk_buff **head,
1364 if (*(u8 *)iph != 0x45) 1364 if (*(u8 *)iph != 0x45)
1365 goto out_unlock; 1365 goto out_unlock;
1366 1366
1367 if (unlikely(ip_fast_csum((u8 *)iph, iph->ihl))) 1367 if (unlikely(ip_fast_csum((u8 *)iph, 5)))
1368 goto out_unlock; 1368 goto out_unlock;
1369 1369
1370 id = ntohl(*(__be32 *)&iph->id); 1370 id = ntohl(*(__be32 *)&iph->id);
@@ -1380,7 +1380,6 @@ static struct sk_buff **inet_gro_receive(struct sk_buff **head,
1380 iph2 = ip_hdr(p); 1380 iph2 = ip_hdr(p);
1381 1381
1382 if ((iph->protocol ^ iph2->protocol) | 1382 if ((iph->protocol ^ iph2->protocol) |
1383 (iph->tos ^ iph2->tos) |
1384 ((__force u32)iph->saddr ^ (__force u32)iph2->saddr) | 1383 ((__force u32)iph->saddr ^ (__force u32)iph2->saddr) |
1385 ((__force u32)iph->daddr ^ (__force u32)iph2->daddr)) { 1384 ((__force u32)iph->daddr ^ (__force u32)iph2->daddr)) {
1386 NAPI_GRO_CB(p)->same_flow = 0; 1385 NAPI_GRO_CB(p)->same_flow = 0;
@@ -1390,6 +1389,7 @@ static struct sk_buff **inet_gro_receive(struct sk_buff **head,
1390 /* All fields must match except length and checksum. */ 1389 /* All fields must match except length and checksum. */
1391 NAPI_GRO_CB(p)->flush |= 1390 NAPI_GRO_CB(p)->flush |=
1392 (iph->ttl ^ iph2->ttl) | 1391 (iph->ttl ^ iph2->ttl) |
1392 (iph->tos ^ iph2->tos) |
1393 ((u16)(ntohs(iph2->id) + NAPI_GRO_CB(p)->count) ^ id); 1393 ((u16)(ntohs(iph2->id) + NAPI_GRO_CB(p)->count) ^ id);
1394 1394
1395 NAPI_GRO_CB(p)->flush |= flush; 1395 NAPI_GRO_CB(p)->flush |= flush;