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

Reply via email to