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