udp: fix poll()
Michael reported an UDP breakage caused by the commitb65ac44674
("udp: try to avoid 2 cache miss on dequeue"). The function __first_packet_length() can update the checksum bits of the pending skb, making the scratched area out-of-sync, and setting skb->csum, if the skb was previously in need of checksum validation. On later recvmsg() for such skb, checksum validation will be invoked again - due to the wrong udp_skb_csum_unnecessary() value - and will fail, causing the valid skb to be dropped. This change addresses the issue refreshing the scratch area in __first_packet_length() after the possible checksum update. Fixes:b65ac44674
("udp: try to avoid 2 cache miss on dequeue") Reported-by: Michael Ellerman <mpe@ellerman.id.au> Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org> Signed-off-by: Paolo Abeni <pabeni@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
4b943faedf
commit
9bd780f5e0
|
@ -1446,16 +1446,23 @@ static struct sk_buff *__first_packet_length(struct sock *sk,
|
||||||
{
|
{
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
|
|
||||||
while ((skb = skb_peek(rcvq)) != NULL &&
|
while ((skb = skb_peek(rcvq)) != NULL) {
|
||||||
udp_lib_checksum_complete(skb)) {
|
if (udp_lib_checksum_complete(skb)) {
|
||||||
__UDP_INC_STATS(sock_net(sk), UDP_MIB_CSUMERRORS,
|
__UDP_INC_STATS(sock_net(sk), UDP_MIB_CSUMERRORS,
|
||||||
IS_UDPLITE(sk));
|
IS_UDPLITE(sk));
|
||||||
__UDP_INC_STATS(sock_net(sk), UDP_MIB_INERRORS,
|
__UDP_INC_STATS(sock_net(sk), UDP_MIB_INERRORS,
|
||||||
IS_UDPLITE(sk));
|
IS_UDPLITE(sk));
|
||||||
atomic_inc(&sk->sk_drops);
|
atomic_inc(&sk->sk_drops);
|
||||||
__skb_unlink(skb, rcvq);
|
__skb_unlink(skb, rcvq);
|
||||||
*total += skb->truesize;
|
*total += skb->truesize;
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
|
} else {
|
||||||
|
/* the csum related bits could be changed, refresh
|
||||||
|
* the scratch area
|
||||||
|
*/
|
||||||
|
udp_set_dev_scratch(skb);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return skb;
|
return skb;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue