[UDP]: UDP can use sk_hash to speedup lookups
In a prior patch, I introduced a sk_hash field (__sk_common.skc_hash) to let tcp lookups use one cache line per unmatched entry instead of two. We can also use sk_hash to speedup UDP part as well. We store in sk_hash the hnum value, and use sk->sk_hash (same cache line than 'next' pointer), instead of inet->num (different cache line) Note : We still have a false sharing problem for SMP machines, because sock_hold(sock) dirties the cache line containing the 'next' pointer. Not counting the udp_hash_lock rwlock. (did someone mentioned RCU ? :) ) Signed-off-by: Eric Dumazet <dada1@cosmosbay.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
4768fbcbcf
commit
95f30b336b
2 changed files with 7 additions and 6 deletions
|
@ -120,7 +120,7 @@ static inline int __udp_lib_lport_inuse(__u16 num, struct hlist_head udptable[])
|
||||||
struct hlist_node *node;
|
struct hlist_node *node;
|
||||||
|
|
||||||
sk_for_each(sk, node, &udptable[num & (UDP_HTABLE_SIZE - 1)])
|
sk_for_each(sk, node, &udptable[num & (UDP_HTABLE_SIZE - 1)])
|
||||||
if (inet_sk(sk)->num == num)
|
if (sk->sk_hash == num)
|
||||||
return 1;
|
return 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -191,7 +191,7 @@ gotit:
|
||||||
head = &udptable[snum & (UDP_HTABLE_SIZE - 1)];
|
head = &udptable[snum & (UDP_HTABLE_SIZE - 1)];
|
||||||
|
|
||||||
sk_for_each(sk2, node, head)
|
sk_for_each(sk2, node, head)
|
||||||
if (inet_sk(sk2)->num == snum &&
|
if (sk2->sk_hash == snum &&
|
||||||
sk2 != sk &&
|
sk2 != sk &&
|
||||||
(!sk2->sk_reuse || !sk->sk_reuse) &&
|
(!sk2->sk_reuse || !sk->sk_reuse) &&
|
||||||
(!sk2->sk_bound_dev_if || !sk->sk_bound_dev_if
|
(!sk2->sk_bound_dev_if || !sk->sk_bound_dev_if
|
||||||
|
@ -200,6 +200,7 @@ gotit:
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
inet_sk(sk)->num = snum;
|
inet_sk(sk)->num = snum;
|
||||||
|
sk->sk_hash = snum;
|
||||||
if (sk_unhashed(sk)) {
|
if (sk_unhashed(sk)) {
|
||||||
head = &udptable[snum & (UDP_HTABLE_SIZE - 1)];
|
head = &udptable[snum & (UDP_HTABLE_SIZE - 1)];
|
||||||
sk_add_node(sk, head);
|
sk_add_node(sk, head);
|
||||||
|
@ -247,7 +248,7 @@ static struct sock *__udp4_lib_lookup(__be32 saddr, __be16 sport,
|
||||||
sk_for_each(sk, node, &udptable[hnum & (UDP_HTABLE_SIZE - 1)]) {
|
sk_for_each(sk, node, &udptable[hnum & (UDP_HTABLE_SIZE - 1)]) {
|
||||||
struct inet_sock *inet = inet_sk(sk);
|
struct inet_sock *inet = inet_sk(sk);
|
||||||
|
|
||||||
if (inet->num == hnum && !ipv6_only_sock(sk)) {
|
if (sk->sk_hash == hnum && !ipv6_only_sock(sk)) {
|
||||||
int score = (sk->sk_family == PF_INET ? 1 : 0);
|
int score = (sk->sk_family == PF_INET ? 1 : 0);
|
||||||
if (inet->rcv_saddr) {
|
if (inet->rcv_saddr) {
|
||||||
if (inet->rcv_saddr != daddr)
|
if (inet->rcv_saddr != daddr)
|
||||||
|
@ -296,7 +297,7 @@ static inline struct sock *udp_v4_mcast_next(struct sock *sk,
|
||||||
sk_for_each_from(s, node) {
|
sk_for_each_from(s, node) {
|
||||||
struct inet_sock *inet = inet_sk(s);
|
struct inet_sock *inet = inet_sk(s);
|
||||||
|
|
||||||
if (inet->num != hnum ||
|
if (s->sk_hash != hnum ||
|
||||||
(inet->daddr && inet->daddr != rmt_addr) ||
|
(inet->daddr && inet->daddr != rmt_addr) ||
|
||||||
(inet->dport != rmt_port && inet->dport) ||
|
(inet->dport != rmt_port && inet->dport) ||
|
||||||
(inet->rcv_saddr && inet->rcv_saddr != loc_addr) ||
|
(inet->rcv_saddr && inet->rcv_saddr != loc_addr) ||
|
||||||
|
|
|
@ -71,7 +71,7 @@ static struct sock *__udp6_lib_lookup(struct in6_addr *saddr, __be16 sport,
|
||||||
sk_for_each(sk, node, &udptable[hnum & (UDP_HTABLE_SIZE - 1)]) {
|
sk_for_each(sk, node, &udptable[hnum & (UDP_HTABLE_SIZE - 1)]) {
|
||||||
struct inet_sock *inet = inet_sk(sk);
|
struct inet_sock *inet = inet_sk(sk);
|
||||||
|
|
||||||
if (inet->num == hnum && sk->sk_family == PF_INET6) {
|
if (sk->sk_hash == hnum && sk->sk_family == PF_INET6) {
|
||||||
struct ipv6_pinfo *np = inet6_sk(sk);
|
struct ipv6_pinfo *np = inet6_sk(sk);
|
||||||
int score = 0;
|
int score = 0;
|
||||||
if (inet->dport) {
|
if (inet->dport) {
|
||||||
|
@ -309,7 +309,7 @@ static struct sock *udp_v6_mcast_next(struct sock *sk,
|
||||||
sk_for_each_from(s, node) {
|
sk_for_each_from(s, node) {
|
||||||
struct inet_sock *inet = inet_sk(s);
|
struct inet_sock *inet = inet_sk(s);
|
||||||
|
|
||||||
if (inet->num == num && s->sk_family == PF_INET6) {
|
if (s->sk_hash == num && s->sk_family == PF_INET6) {
|
||||||
struct ipv6_pinfo *np = inet6_sk(s);
|
struct ipv6_pinfo *np = inet6_sk(s);
|
||||||
if (inet->dport) {
|
if (inet->dport) {
|
||||||
if (inet->dport != rmt_port)
|
if (inet->dport != rmt_port)
|
||||||
|
|
Loading…
Add table
Reference in a new issue