diff options
author | Eric Dumazet <eric.dumazet@gmail.com> | 2011-11-09 08:24:35 +0100 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-11-09 22:36:27 +0100 |
commit | d826eb14ecef3574b6b3be55e5f4329f4a76fbf3 (patch) | |
tree | e072ee768f065be430543709d48f08a36f4eed2d /net/ipv6/raw.c | |
parent | ipv4: reduce percpu needs for icmpmsg mibs (diff) | |
download | linux-d826eb14ecef3574b6b3be55e5f4329f4a76fbf3.tar.xz linux-d826eb14ecef3574b6b3be55e5f4329f4a76fbf3.zip |
ipv4: PKTINFO doesnt need dst reference
Le lundi 07 novembre 2011 à 15:33 +0100, Eric Dumazet a écrit :
> At least, in recent kernels we dont change dst->refcnt in forwarding
> patch (usinf NOREF skb->dst)
>
> One particular point is the atomic_inc(dst->refcnt) we have to perform
> when queuing an UDP packet if socket asked PKTINFO stuff (for example a
> typical DNS server has to setup this option)
>
> I have one patch somewhere that stores the information in skb->cb[] and
> avoid the atomic_{inc|dec}(dst->refcnt).
>
OK I found it, I did some extra tests and believe its ready.
[PATCH net-next] ipv4: IP_PKTINFO doesnt need dst reference
When a socket uses IP_PKTINFO notifications, we currently force a dst
reference for each received skb. Reader has to access dst to get needed
information (rt_iif & rt_spec_dst) and must release dst reference.
We also forced a dst reference if skb was put in socket backlog, even
without IP_PKTINFO handling. This happens under stress/load.
We can instead store the needed information in skb->cb[], so that only
softirq handler really access dst, improving cache hit ratios.
This removes two atomic operations per packet, and false sharing as
well.
On a benchmark using a mono threaded receiver (doing only recvmsg()
calls), I can reach 720.000 pps instead of 570.000 pps.
IP_PKTINFO is typically used by DNS servers, and any multihomed aware
UDP application.
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/raw.c')
-rw-r--r-- | net/ipv6/raw.c | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 331af3b882ac..204f2e833f04 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c @@ -383,7 +383,8 @@ static inline int rawv6_rcv_skb(struct sock *sk, struct sk_buff *skb) } /* Charge it to the socket. */ - if (ip_queue_rcv_skb(sk, skb) < 0) { + skb_dst_drop(skb); + if (sock_queue_rcv_skb(sk, skb) < 0) { kfree_skb(skb); return NET_RX_DROP; } |