[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <463B4878.4060902@sw.ru>
Date: Fri, 04 May 2007 18:51:36 +0400
From: Pavel Emelianov <xemul@...ru>
To: David Miller <davem@...emloft.net>,
Linux Netdev List <netdev@...r.kernel.org>
CC: devel@...nvz.org
Subject: [PATCH] Consolidate udp hash calculations
Make access to udphash/udplitehash symmetrical to inet hashes.
This may also help network namespaces, since they tend to use
one hash for different namespaces by selecting the hash chain
depending on a hash value and the namespace.
Signed-off-by: Pavel Emelianov <xemul@...nvz.org>
---
diff --git a/include/linux/udp.h b/include/linux/udp.h
index 6de445c..a40ccd4 100644
--- a/include/linux/udp.h
+++ b/include/linux/udp.h
@@ -49,6 +49,11 @@ static inline struct udphdr *udp_hdr(con
#include <net/inet_sock.h>
#define UDP_HTABLE_SIZE 128
+static inline unsigned int udp_hashfn(unsigned int num)
+{
+ return num & (UDP_HTABLE_SIZE - 1);
+}
+
struct udp_sock {
/* inet_sock has to be the first member */
struct inet_sock inet;
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 113e0c4..8ea1c81 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -132,7 +132,7 @@ static inline int __udp_lib_port_inuse(u
struct hlist_node *node;
struct inet_sock *inet;
- sk_for_each(sk, node, &udptable[hash & (UDP_HTABLE_SIZE - 1)]) {
+ sk_for_each(sk, node, &udptable[udp_hashfn(hash)]) {
if (sk->sk_hash != hash)
continue;
inet = inet_sk(sk);
@@ -159,7 +159,6 @@ int __udp_lib_get_port(struct sock *sk,
const struct sock *sk2 ) )
{
struct hlist_node *node;
- struct hlist_head *head;
struct sock *sk2;
unsigned int hash;
int error = 1;
@@ -175,10 +174,11 @@ int __udp_lib_get_port(struct sock *sk,
best = result = *port_rover;
for (i = 0; i < UDP_HTABLE_SIZE; i++, result++) {
int size;
+ struct hlist_head *head;
hash = hash_port_and_addr(result,
inet_sk(sk)->rcv_saddr);
- head = &udptable[hash & (UDP_HTABLE_SIZE - 1)];
+ head = &udptable[udp_hashfn(hash)];
if (hlist_empty(head)) {
if (result > sysctl_local_port_range[1])
result = sysctl_local_port_range[0] +
@@ -222,9 +222,7 @@ gotit:
*port_rover = snum = result;
} else {
hash = hash_port_and_addr(snum, 0);
- head = &udptable[hash & (UDP_HTABLE_SIZE - 1)];
-
- sk_for_each(sk2, node, head)
+ sk_for_each(sk2, node, &udptable[udp_hashfn(hash)])
if (sk2->sk_hash == hash &&
sk2 != sk &&
inet_sk(sk2)->num == snum &&
@@ -237,9 +235,7 @@ gotit:
if (inet_sk(sk)->rcv_saddr) {
hash = hash_port_and_addr(snum,
inet_sk(sk)->rcv_saddr);
- head = &udptable[hash & (UDP_HTABLE_SIZE - 1)];
-
- sk_for_each(sk2, node, head)
+ sk_for_each(sk2, node, &udptable[udp_hashfn(hash)])
if (sk2->sk_hash == hash &&
sk2 != sk &&
inet_sk(sk2)->num == snum &&
@@ -255,8 +251,7 @@ gotit:
inet_sk(sk)->num = snum;
sk->sk_hash = hash;
if (sk_unhashed(sk)) {
- head = &udptable[hash & (UDP_HTABLE_SIZE - 1)];
- sk_add_node(sk, head);
+ sk_add_node(sk, &udptable[udp_hashfn(hash)]);
sock_prot_inc_use(sk->sk_prot);
}
error = 0;
@@ -304,7 +299,7 @@ static struct sock *__udp4_lib_lookup(__
lookup:
- sk_for_each(sk, node, &udptable[hash & (UDP_HTABLE_SIZE - 1)]) {
+ sk_for_each(sk, node, &udptable[udp_hashfn(hash)]) {
struct inet_sock *inet = inet_sk(sk);
if (sk->sk_hash != hash || ipv6_only_sock(sk) ||
@@ -1205,8 +1200,8 @@ static int __udp4_lib_mcast_deliver(stru
read_lock(&udp_hash_lock);
- sk = sk_head(&udptable[hash & (UDP_HTABLE_SIZE - 1)]);
- skw = sk_head(&udptable[hashwild & (UDP_HTABLE_SIZE - 1)]);
+ sk = sk_head(&udptable[udp_hashfn(hash)]);
+ skw = sk_head(&udptable[udp_hashfn(hashwild)]);
sk = udp_v4_mcast_next(sk, hash, hport, daddr, uh->source, saddr, dif);
if (!sk) {
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index b083c09..a0a8915 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -67,7 +67,7 @@ static struct sock *__udp6_lib_lookup(st
int badness = -1;
read_lock(&udp_hash_lock);
- sk_for_each(sk, node, &udptable[hnum & (UDP_HTABLE_SIZE - 1)]) {
+ sk_for_each(sk, node, &udptable[udp_hashfn(hnum)]) {
struct inet_sock *inet = inet_sk(sk);
if (sk->sk_hash == hnum && sk->sk_family == PF_INET6) {
@@ -350,7 +350,7 @@ static int __udp6_lib_mcast_deliver(stru
int dif;
read_lock(&udp_hash_lock);
- sk = sk_head(&udptable[ntohs(uh->dest) & (UDP_HTABLE_SIZE - 1)]);
+ sk = sk_head(&udptable[udp_hashfn(ntohs(uh->dest))]);
dif = inet6_iif(skb);
sk = udp_v6_mcast_next(sk, uh->dest, daddr, uh->source, saddr, dif);
if (!sk) {
-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists