Commit fd9e6354 authored by Pavel Emelyanov's avatar Pavel Emelyanov Committed by David S. Miller

[INET]: Omit double hash calculations in xxx_frag_intern

Since the hash value is already calculated in xxx_find, we can 
simply use it later. This is already done in netfilter code, 
so make the same in ipv4 and ipv6.
Signed-off-by: default avatarPavel Emelyanov <xemul@openvz.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent be076645
...@@ -212,17 +212,14 @@ static void ip_expire(unsigned long arg) ...@@ -212,17 +212,14 @@ static void ip_expire(unsigned long arg)
/* Creation primitives. */ /* Creation primitives. */
static struct ipq *ip_frag_intern(struct ipq *qp_in) static struct ipq *ip_frag_intern(struct ipq *qp_in, unsigned int hash)
{ {
struct ipq *qp; struct ipq *qp;
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
struct hlist_node *n; struct hlist_node *n;
#endif #endif
unsigned int hash;
write_lock(&ip4_frags.lock); write_lock(&ip4_frags.lock);
hash = ipqhashfn(qp_in->id, qp_in->saddr, qp_in->daddr,
qp_in->protocol);
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
/* With SMP race we have to recheck hash table, because /* With SMP race we have to recheck hash table, because
* such entry could be created on other cpu, while we * such entry could be created on other cpu, while we
...@@ -257,7 +254,7 @@ static struct ipq *ip_frag_intern(struct ipq *qp_in) ...@@ -257,7 +254,7 @@ static struct ipq *ip_frag_intern(struct ipq *qp_in)
} }
/* Add an entry to the 'ipq' queue for a newly received IP datagram. */ /* Add an entry to the 'ipq' queue for a newly received IP datagram. */
static struct ipq *ip_frag_create(struct iphdr *iph, u32 user) static struct ipq *ip_frag_create(struct iphdr *iph, u32 user, unsigned int h)
{ {
struct ipq *qp; struct ipq *qp;
...@@ -278,7 +275,7 @@ static struct ipq *ip_frag_create(struct iphdr *iph, u32 user) ...@@ -278,7 +275,7 @@ static struct ipq *ip_frag_create(struct iphdr *iph, u32 user)
spin_lock_init(&qp->q.lock); spin_lock_init(&qp->q.lock);
atomic_set(&qp->q.refcnt, 1); atomic_set(&qp->q.refcnt, 1);
return ip_frag_intern(qp); return ip_frag_intern(qp, h);
out_nomem: out_nomem:
LIMIT_NETDEBUG(KERN_ERR "ip_frag_create: no memory left !\n"); LIMIT_NETDEBUG(KERN_ERR "ip_frag_create: no memory left !\n");
...@@ -313,7 +310,7 @@ static inline struct ipq *ip_find(struct iphdr *iph, u32 user) ...@@ -313,7 +310,7 @@ static inline struct ipq *ip_find(struct iphdr *iph, u32 user)
} }
read_unlock(&ip4_frags.lock); read_unlock(&ip4_frags.lock);
return ip_frag_create(iph, user); return ip_frag_create(iph, user, hash);
} }
/* Is the fragment too far ahead to be part of ipq? */ /* Is the fragment too far ahead to be part of ipq? */
......
...@@ -233,16 +233,15 @@ static void ip6_frag_expire(unsigned long data) ...@@ -233,16 +233,15 @@ static void ip6_frag_expire(unsigned long data)
/* Creation primitives. */ /* Creation primitives. */
static struct frag_queue *ip6_frag_intern(struct frag_queue *fq_in) static struct frag_queue *ip6_frag_intern(struct frag_queue *fq_in,
unsigned int hash)
{ {
struct frag_queue *fq; struct frag_queue *fq;
unsigned int hash;
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
struct hlist_node *n; struct hlist_node *n;
#endif #endif
write_lock(&ip6_frags.lock); write_lock(&ip6_frags.lock);
hash = ip6qhashfn(fq_in->id, &fq_in->saddr, &fq_in->daddr);
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
hlist_for_each_entry(fq, n, &ip6_frags.hash[hash], q.list) { hlist_for_each_entry(fq, n, &ip6_frags.hash[hash], q.list) {
if (fq->id == fq_in->id && if (fq->id == fq_in->id &&
...@@ -273,7 +272,7 @@ static struct frag_queue *ip6_frag_intern(struct frag_queue *fq_in) ...@@ -273,7 +272,7 @@ static struct frag_queue *ip6_frag_intern(struct frag_queue *fq_in)
static struct frag_queue * static struct frag_queue *
ip6_frag_create(__be32 id, struct in6_addr *src, struct in6_addr *dst, ip6_frag_create(__be32 id, struct in6_addr *src, struct in6_addr *dst,
struct inet6_dev *idev) struct inet6_dev *idev, unsigned int hash)
{ {
struct frag_queue *fq; struct frag_queue *fq;
...@@ -290,7 +289,7 @@ ip6_frag_create(__be32 id, struct in6_addr *src, struct in6_addr *dst, ...@@ -290,7 +289,7 @@ ip6_frag_create(__be32 id, struct in6_addr *src, struct in6_addr *dst,
spin_lock_init(&fq->q.lock); spin_lock_init(&fq->q.lock);
atomic_set(&fq->q.refcnt, 1); atomic_set(&fq->q.refcnt, 1);
return ip6_frag_intern(fq); return ip6_frag_intern(fq, hash);
oom: oom:
IP6_INC_STATS_BH(idev, IPSTATS_MIB_REASMFAILS); IP6_INC_STATS_BH(idev, IPSTATS_MIB_REASMFAILS);
...@@ -318,7 +317,7 @@ fq_find(__be32 id, struct in6_addr *src, struct in6_addr *dst, ...@@ -318,7 +317,7 @@ fq_find(__be32 id, struct in6_addr *src, struct in6_addr *dst,
} }
read_unlock(&ip6_frags.lock); read_unlock(&ip6_frags.lock);
return ip6_frag_create(id, src, dst, idev); return ip6_frag_create(id, src, dst, idev, hash);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment