diff options
Diffstat (limited to 'net/ipv4/udp.c')
-rw-r--r-- | net/ipv4/udp.c | 31 |
1 files changed, 10 insertions, 21 deletions
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index e980869f18..b32cf2eeeb 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -411,8 +411,6 @@ INDIRECT_CALLABLE_SCOPE u32 udp_ehashfn(const struct net *net, const __be32 laddr, const __u16 lport, const __be32 faddr, const __be16 fport) { - static u32 udp_ehash_secret __read_mostly; - net_get_random_once(&udp_ehash_secret, sizeof(udp_ehash_secret)); return __inet_ehashfn(laddr, lport, faddr, fport, @@ -429,21 +427,15 @@ static struct sock *udp4_lib_lookup2(struct net *net, { struct sock *sk, *result; int score, badness; - bool need_rescore; result = NULL; badness = 0; udp_portaddr_for_each_entry_rcu(sk, &hslot2->head) { - need_rescore = false; -rescore: - score = compute_score(need_rescore ? result : sk, net, saddr, - sport, daddr, hnum, dif, sdif); + score = compute_score(sk, net, saddr, sport, + daddr, hnum, dif, sdif); if (score > badness) { badness = score; - if (need_rescore) - continue; - if (sk->sk_state == TCP_ESTABLISHED) { result = sk; continue; @@ -464,14 +456,9 @@ rescore: if (IS_ERR(result)) continue; - /* compute_score is too long of a function to be - * inlined, and calling it again here yields - * measureable overhead for some - * workloads. Work around it by jumping - * backwards to rescore 'result'. - */ - need_rescore = true; - goto rescore; + badness = compute_score(result, net, saddr, sport, + daddr, hnum, dif, sdif); + } } return result; @@ -1609,7 +1596,8 @@ int udp_init_sock(struct sock *sk) void skb_consume_udp(struct sock *sk, struct sk_buff *skb, int len) { - sk_peek_offset_bwd(sk, len); + if (unlikely(READ_ONCE(udp_sk(sk)->peeking_with_offset))) + sk_peek_offset_bwd(sk, len); if (!skb_unref(skb)) return; @@ -2589,11 +2577,12 @@ int udp_v4_early_demux(struct sk_buff *skb) uh->source, iph->saddr, dif, sdif); } - if (!sk || !refcount_inc_not_zero(&sk->sk_refcnt)) + if (!sk) return 0; skb->sk = sk; - skb->destructor = sock_efree; + DEBUG_NET_WARN_ON_ONCE(sk_is_refcounted(sk)); + skb->destructor = sock_pfree; dst = rcu_dereference(sk->sk_rx_dst); if (dst) |