[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: Pavel Emelyanov <xemul@openvz.org> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
be07664599
commit
fd9e63544c
|
@ -212,17 +212,14 @@ out:
|
||||||
|
|
||||||
/* 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)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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)
|
||||||
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)
|
||||||
}
|
}
|
||||||
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 @@ out:
|
||||||
/* 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)
|
||||||
|
|
||||||
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,
|
||||||
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,
|
||||||
}
|
}
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue