On Fri, Dec 02, 2005 at 07:47:45AM +0100, Eric Dumazet wrote: > Herbert Xu a écrit : > >Jayachandran C. <[EMAIL PROTECTED]> wrote: [incorrect patch deleted] > > > >This is wrong. If we're peeking, we've incremented the refcount of the > >skb without taking it off the list. So if it isn't on the list anymore, > >we should simply drop our reference. If it's still on the list, we need > >to drop our reference twice which is what this code is trying to do. > > > >Cheers, > > Then maybe we could just do something like that : > > if (skb == skb_peek(&sk->sk_receive_queue)) { > __skb_unlink(skb, &sk->sk_receive_queue); > atomic_dec(&skb->users); /* drop reference */ > } > > This should avoid inlining kfree_skb() with 2 conditional branches...
If anybody is interested, I have attached the above change in patch format. This changes udp_recvmsg(), udpv6_recvmsg(), and rawv6_recvmsg(). I wonder why raw_recvmsg() does not have similar code... This patch cleans up the MSG_PEEK handling in udp_recvmsg(), udpv6_recvmsg(), and rawv6_recvmsg() Change suggested by Eric Dumazet. Signed-off-by: Jayachandran C. <c.jayachandran at gmail.com> --- ipv4/udp.c | 5 +---- ipv6/raw.c | 5 +---- ipv6/udp.c | 5 +---- 3 files changed, 3 insertions(+), 12 deletions(-) diff -ur linux-2.6.15-rc3-git1.clean/net/ipv4/udp.c linux-2.6.15-rc3-git1/net/ipv4/udp.c --- linux-2.6.15-rc3-git1.clean/net/ipv4/udp.c 2005-12-01 11:25:27.000000000 +0530 +++ linux-2.6.15-rc3-git1/net/ipv4/udp.c 2005-12-02 14:48:40.000000000 +0530 @@ -848,15 +848,12 @@ /* Clear queue. */ if (flags&MSG_PEEK) { - int clear = 0; spin_lock_bh(&sk->sk_receive_queue.lock); if (skb == skb_peek(&sk->sk_receive_queue)) { __skb_unlink(skb, &sk->sk_receive_queue); - clear = 1; + atomic_dec(&skb->users); /* drop reference */ } spin_unlock_bh(&sk->sk_receive_queue.lock); - if (clear) - kfree_skb(skb); } skb_free_datagram(sk, skb); diff -ur linux-2.6.15-rc3-git1.clean/net/ipv6/raw.c linux-2.6.15-rc3-git1/net/ipv6/raw.c --- linux-2.6.15-rc3-git1.clean/net/ipv6/raw.c 2005-12-01 11:25:28.000000000 +0530 +++ linux-2.6.15-rc3-git1/net/ipv6/raw.c 2005-12-02 14:49:39.000000000 +0530 @@ -435,15 +435,12 @@ csum_copy_err: /* Clear queue. */ if (flags&MSG_PEEK) { - int clear = 0; spin_lock_bh(&sk->sk_receive_queue.lock); if (skb == skb_peek(&sk->sk_receive_queue)) { __skb_unlink(skb, &sk->sk_receive_queue); - clear = 1; + atomic_dec(&skb->users); /* drop reference */ } spin_unlock_bh(&sk->sk_receive_queue.lock); - if (clear) - kfree_skb(skb); } /* Error for blocking case is chosen to masquerade diff -ur linux-2.6.15-rc3-git1.clean/net/ipv6/udp.c linux-2.6.15-rc3-git1/net/ipv6/udp.c --- linux-2.6.15-rc3-git1.clean/net/ipv6/udp.c 2005-12-01 11:25:28.000000000 +0530 +++ linux-2.6.15-rc3-git1/net/ipv6/udp.c 2005-12-02 14:50:10.000000000 +0530 @@ -302,15 +302,12 @@ csum_copy_err: /* Clear queue. */ if (flags&MSG_PEEK) { - int clear = 0; spin_lock_bh(&sk->sk_receive_queue.lock); if (skb == skb_peek(&sk->sk_receive_queue)) { __skb_unlink(skb, &sk->sk_receive_queue); - clear = 1; + atomic_dec(&skb->users); /* drop reference */ } spin_unlock_bh(&sk->sk_receive_queue.lock); - if (clear) - kfree_skb(skb); } skb_free_datagram(sk, skb); - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html