summaryrefslogtreecommitdiff
path: root/net/ipv4/udp.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2015-08-20 11:48:56 +0200
committerIngo Molnar <mingo@kernel.org>2015-08-20 11:48:56 +0200
commit40a2ea1bd988e3bbdb07a0708681fdb05cd7d267 (patch)
tree05806aaa27a4b0516a14a8ccf703c1501500e588 /net/ipv4/udp.c
parenta897b5f0393a8a05d230c9248dc5324fb30720a0 (diff)
parent196676497f2507966f99abef63bede6a8550f8b3 (diff)
downloadlinux-40a2ea1bd988e3bbdb07a0708681fdb05cd7d267.tar.gz
linux-40a2ea1bd988e3bbdb07a0708681fdb05cd7d267.tar.bz2
linux-40a2ea1bd988e3bbdb07a0708681fdb05cd7d267.zip
Merge branch 'perf/urgent' into perf/core, to pick up fixes before adding more changes
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'net/ipv4/udp.c')
-rw-r--r--net/ipv4/udp.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 83aa604f9273..1b8c5ba7d5f7 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -1995,12 +1995,19 @@ void udp_v4_early_demux(struct sk_buff *skb)
skb->sk = sk;
skb->destructor = sock_efree;
- dst = sk->sk_rx_dst;
+ dst = READ_ONCE(sk->sk_rx_dst);
if (dst)
dst = dst_check(dst, 0);
- if (dst)
- skb_dst_set_noref(skb, dst);
+ if (dst) {
+ /* DST_NOCACHE can not be used without taking a reference */
+ if (dst->flags & DST_NOCACHE) {
+ if (likely(atomic_inc_not_zero(&dst->__refcnt)))
+ skb_dst_set(skb, dst);
+ } else {
+ skb_dst_set_noref(skb, dst);
+ }
+ }
}
int udp_rcv(struct sk_buff *skb)