Re: [Bug #16626] Machine hangs with EIP at skb_copy_and_csum_dev

From: Plamen Petrov
Date: Sun Sep 12 2010 - 02:55:47 EST


ÐÐ 08.9.2010 Ð. 23:21, Rafael J. Wysocki ÐÐÐÐÑÐ:
On Wednesday, September 08, 2010, David Miller wrote:
From: Jarek Poplawski<jarkao2@xxxxxxxxx>
Date: Wed, 8 Sep 2010 06:20:04 +0000

We need both of them. I hope David could add this too:

Tested-by: Plamen Petrov<pvp-lsts@xxxxxxxxxxxxxx>

Done, and applied, thanks :-)

Please kindly let me know when Linus gets them, so that I can close the bug.

Rafael

Now that both commits that fix my problems are in Linus' tree, the
bug can be closed, but these fixes should go in 2.6.35.y, too.
So, CCing -stable.

Fix 1:
commit 3d3be4333fdf6faa080947b331a6a19bce1a4f57

gro: fix different skb headrooms

Packets entering GRO might have different headrooms, even for a given
flow (because of implementation details in drivers, like copybreak).
We cant force drivers to deliver packets with a fixed headroom.

1) fix skb_segment()

skb_segment() makes the false assumption headrooms of fragments are same
than the head. When CHECKSUM_PARTIAL is used, this can give csum_start
errors, and crash later in skb_copy_and_csum_dev()

2) allocate a minimal skb for head of frag_list

skb_gro_receive() uses netdev_alloc_skb(headroom + skb_gro_offset(p)) to
allocate a fresh skb. This adds NET_SKB_PAD to a padding already
provided by netdevice, depending on various things, like copybreak.

Use alloc_skb() to allocate an exact padding, to reduce cache line
needs:
NET_SKB_PAD + NET_IP_ALIGN

bugzilla : https://bugzilla.kernel.org/show_bug.cgi?id=16626

Many thanks to Plamen Petrov, testing many debugging patches !
With help of Jarek Poplawski.

Reported-by: Plamen Petrov <pvp-lsts@xxxxxxxxxxxxxx>
Signed-off-by: Eric Dumazet <eric.dumazet@xxxxxxxxx>
CC: Jarek Poplawski <jarkao2@xxxxxxxxx>
Signed-off-by: David S. Miller <davem@xxxxxxxxxxxxx>

Fix 2:
commit 64289c8e6851bca0e589e064c9a5c9fbd6ae5dd4

gro: Re-fix different skb headrooms

The patch: "gro: fix different skb headrooms" in its part:
"2) allocate a minimal skb for head of frag_list" is buggy. The copied
skb has p->data set at the ip header at the moment, and skb_gro_offset
is the length of ip + tcp headers. So, after the change the length of
mac header is skipped. Later skb_set_mac_header() sets it into the
NET_SKB_PAD area (if it's long enough) and ip header is misaligned at
NET_SKB_PAD + NET_IP_ALIGN offset. There is no reason to assume the
original skb was wrongly allocated, so let's copy it as it was.

bugzilla : https://bugzilla.kernel.org/show_bug.cgi?id=16626
fixes commit: 3d3be4333fdf6faa080947b331a6a19bce1a4f57

Reported-by: Plamen Petrov <pvp-lsts@xxxxxxxxxxxxxx>
Signed-off-by: Jarek Poplawski <jarkao2@xxxxxxxxx>
CC: Eric Dumazet <eric.dumazet@xxxxxxxxx>
Acked-by: Eric Dumazet <eric.dumazet@xxxxxxxxx>
Tested-by: Plamen Petrov <pvp-lsts@xxxxxxxxxxxxxx>
Signed-off-by: David S. Miller <davem@xxxxxxxxxxxxx>

Thanks,
Plamen
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/