net-next: broken IP_PKTINFO [was Re: [PATCH] net: release skb->dst in sock_queue_rcv_skb()]
From: Mark McLoughlin <hidden>
Date: 2008-12-17 11:25:23
Hi, On Wed, 2008-11-26 at 01:00 +0100, Eric Dumazet wrote:
quoted hunk ↗ jump to hunk
[PATCH] net: release skb->dst in sock_queue_rcv_skb() When queuing a skb to sk->sk_receive_queue, we can release its dst, not anymore needed. Since current cpu did the dst_hold(), refcount is probably still hot int this cpu caches. This avoids readers to access the original dst to decrement its refcount, possibly a long time after packet reception. This should speedup UDP and RAW receive path. Signed-off-by: Eric Dumazet <redacted> plain text document attachment (sock_queue_rcv_skb.patch)diff --git a/net/core/sock.c b/net/core/sock.c index a4e840e..b287645 100644 --- a/net/core/sock.c +++ b/net/core/sock.c@@ -289,7 +289,11 @@ int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) skb->dev = NULL; skb_set_owner_r(skb, sk); - + /* + * release dst right now while its hot + */ + dst_release(skb->dst); + skb->dst = NULL;
IP_PKTINFO cmsg data is one post-queueing user:
static void ip_cmsg_recv_pktinfo(struct msghdr *msg, struct sk_buff *skb)
{
struct in_pktinfo info;
struct rtable *rt = skb->rtable;
info.ipi_addr.s_addr = ip_hdr(skb)->daddr;
if (rt) {
info.ipi_ifindex = rt->rt_iif;
info.ipi_spec_dst.s_addr = rt->rt_spec_dst;
} else {
info.ipi_ifindex = 0;
info.ipi_spec_dst.s_addr = 0;
}
put_cmsg(msg, SOL_IP, IP_PKTINFO, sizeof(info), &info);
}
(i.e. skb->rtable is NULL at this point)
I'm seeing dnsmasq not working on net-next-2.6 because of this and
reverting commit 7035560 makes things work as expected again.
Cheers,
Mark.