Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 10 Apr 2015 06:55:44 +0000 (UTC)
From:      Gleb Smirnoff <glebius@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r281352 - head/sys/netinet
Message-ID:  <201504100655.t3A6tioW010182@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: glebius
Date: Fri Apr 10 06:55:43 2015
New Revision: 281352
URL: https://svnweb.freebsd.org/changeset/base/281352

Log:
  o Use Jenkins hash. With previous hash, for a single source IP address and
    sequential IP ID case (e.g. ping -f), distribution fell into 8-10 buckets
    out of 64. With Jenkins hash, distribution is even.
  o Add random seed to the hash.
  
  Sponsored by:	Nginx, Inc.

Modified:
  head/sys/netinet/ip_reass.c

Modified: head/sys/netinet/ip_reass.c
==============================================================================
--- head/sys/netinet/ip_reass.c	Fri Apr 10 06:02:37 2015	(r281351)
+++ head/sys/netinet/ip_reass.c	Fri Apr 10 06:55:43 2015	(r281352)
@@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/eventhandler.h>
+#include <sys/hash.h>
 #include <sys/mbuf.h>
 #include <sys/malloc.h>
 #include <sys/lock.h>
@@ -64,8 +65,6 @@ SYSCTL_DECL(_net_inet_ip);
 #define	IPREASS_NHASH_LOG2	6
 #define	IPREASS_NHASH		(1 << IPREASS_NHASH_LOG2)
 #define	IPREASS_HMASK		(IPREASS_NHASH - 1)
-#define	IPREASS_HASH(x,y) \
-	(((((x) & 0xF) | ((((x) >> 8) & 0xF) << 4)) ^ (y)) & IPREASS_HMASK)
 
 struct ipqbucket {
 	TAILQ_HEAD(ipqhead, ipq) head;
@@ -74,6 +73,8 @@ struct ipqbucket {
 
 static VNET_DEFINE(struct ipqbucket, ipq[IPREASS_NHASH]);
 #define	V_ipq		VNET(ipq)
+static VNET_DEFINE(uint32_t, ipq_hashseed);
+#define V_ipq_hashseed   VNET(ipq_hashseed)
 
 #define	IPQ_LOCK(i)	mtx_lock(&V_ipq[i].lock)
 #define	IPQ_TRYLOCK(i)	mtx_trylock(&V_ipq[i].lock)
@@ -146,7 +147,7 @@ ip_reass(struct mbuf *m)
 	struct ipqhead *head;
 	int i, hlen, next;
 	u_int8_t ecn, ecn0;
-	u_short hash;
+	uint32_t hash;
 #ifdef	RSS
 	uint32_t rss_hash, rss_type;
 #endif
@@ -200,7 +201,8 @@ ip_reass(struct mbuf *m)
 	m->m_data += hlen;
 	m->m_len -= hlen;
 
-	hash = IPREASS_HASH(ip->ip_src.s_addr, ip->ip_id);
+	hash = ip->ip_src.s_addr ^ ip->ip_id;
+	hash = jenkins_hash32(&hash, 1, V_ipq_hashseed) & IPREASS_HMASK;
 	head = &V_ipq[hash].head;
 	IPQ_LOCK(hash);
 
@@ -465,6 +467,7 @@ ipreass_init(void)
 		mtx_init(&V_ipq[i].lock, "IP reassembly", NULL,
 		    MTX_DEF | MTX_DUPOK);
 	}
+	V_ipq_hashseed = arc4random();
 	V_maxfragsperpacket = 16;
 	V_ipq_zone = uma_zcreate("ipq", sizeof(struct ipq), NULL, NULL, NULL,
 	    NULL, UMA_ALIGN_PTR, 0);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201504100655.t3A6tioW010182>