afs: use jenkins hash for dcache, vcache tables
authorBenjamin Kaduk <kaduk@mit.edu>
Wed, 14 Jan 2015 01:22:59 +0000 (20:22 -0500)
committerBenjamin Kaduk <kaduk@mit.edu>
Fri, 28 Aug 2015 03:05:12 +0000 (23:05 -0400)
Switch the four dcache and vcache hash tables to use the jenkins
hash from opr.

This requires making DCHash into a full-weight function in order
to properly hash all three inputs; convert all four symbols to
full functions for consistency.  Just pull in <opr/jhash.h> via
afs.h so all consumers (e.g., of VCSIZE) can use it without
modification.

This is the first use of src/opr/ in src/afs/ (outside UKERNEL),
but it is permissible because opr/jhash.h is a standalone
header and there are no C files needed for its implementation which
would require anything from the system.

Change-Id: Ic7f31e7dc548ff2cf13ac087a9e4bbb2b874e03a
Reviewed-on: http://gerrit.openafs.org/11673
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>
Tested-by: BuildBot <buildbot@rampaginggeek.com>

src/afs/afs.h
src/afs/afs_dcache.c
src/afs/afs_prototypes.h
src/afs/afs_vcache.c

index 443bd0b..2dc18fb 100644 (file)
@@ -20,6 +20,9 @@
 #include "afs/afs_consts.h"
 #endif
 
+/* jhash.h is a standalone header and is fine to pull into kernel code. */
+#include <opr/jhash.h>
+
 /*
  * afs_fsfragsize cannot be less than 1023, or some cache-tracking
  * calculations will be incorrect (since we track cache usage in kb).
@@ -82,7 +85,8 @@ extern int afs_shuttingdown;
 #define        NSERVERS        16      /* hash table size for server table */
 #define        NVOLS           64      /* hash table size for volume table */
 #define        NFENTRIES       256     /* hash table size for disk volume table */
-#define        VCSIZE         1024     /* stat cache hash table size */
+#define VCSIZEBITS     10      /* log of stat cache hash table size */
+#define        VCSIZE          (opr_jhash_size(VCSIZEBITS))
 #define CBRSIZE                512     /* call back returns hash table size */
 #define        PIGGYSIZE       1350    /* max piggyback size */
 #define        MAXVOLS         128     /* max vols we can store */
@@ -1336,21 +1340,6 @@ struct afs_FetchOutput {
 
 #define afs_InReadDir(avc) (((avc)->f.states & CReadDir) && (avc)->readdir_pid == MyPidxx2Pid(MyPidxx))
 
-/* The PFlush algorithm makes use of the fact that Fid.Unique is not used in
-  below hash algorithms.  Change it if need be so that flushing algorithm
-  doesn't move things from one hash chain to another
-*/
-/* extern int afs_dhashsize; */
-#define        DCHash(v, c)    ((((v)->Fid.Vnode + (v)->Fid.Volume + (c))) & (afs_dhashsize-1))
-       /*Vnode, Chunk -> Hash table index */
-#define        DVHash(v)       ((((v)->Fid.Vnode + (v)->Fid.Volume )) & (afs_dhashsize-1))
-       /*Vnode -> Other hash table index */
-/* don't hash on the cell, our callback-breaking code sometimes fails to compute
-    the cell correctly, and only scans one hash bucket */
-#define        VCHash(fid)     (((fid)->Fid.Volume + (fid)->Fid.Vnode) & (VCSIZE-1))
-/* Hash only on volume to speed up volume callbacks. */
-#define VCHashV(fid) ((fid)->Fid.Volume & (VCSIZE-1))
-
 extern struct dcache **afs_indexTable; /*Pointers to in-memory dcache entries */
 extern afs_int32 *afs_indexUnique;     /*dcache entry Fid.Unique */
 extern afs_int32 *afs_dvnextTbl;       /*Dcache hash table links */
index 27b0733..56f883d 100644 (file)
@@ -154,6 +154,29 @@ struct afs_cacheOps afs_MemCacheOps = {
 int cacheDiskType;             /*Type of backing disk for cache */
 struct afs_cacheOps *afs_cacheType;
 
+
+/*
+ * The PFlush algorithm makes use of the fact that Fid.Unique is not used in
+ * below hash algorithms.  Change it if need be so that flushing algorithm
+ * doesn't move things from one hash chain to another.
+ */
+/*Vnode, Chunk -> Hash table index */
+int DCHash(struct VenusFid *fid, afs_int32 chunk)
+{
+    afs_uint32 buf[3];
+
+    buf[0] = fid->Fid.Volume;
+    buf[1] = fid->Fid.Vnode;
+    buf[2] = chunk;
+    return opr_jhash(buf, 3, 0) & (afs_dhashsize - 1);
+}
+/*Vnode -> Other hash table index */
+int DVHash(struct VenusFid *fid)
+{
+    return opr_jhash_int2(fid->Fid.Volume, fid->Fid.Vnode, 0) &
+       (afs_dhashsize - 1);
+}
+
 /*!
  * Where is this vcache's entry associated dcache located/
  * \param avc The vcache entry.
index b6eb2df..440567a 100644 (file)
@@ -245,6 +245,8 @@ extern unsigned char *afs_indexFlags;
 extern struct afs_cacheOps *afs_cacheType;
 extern afs_dcache_id_t cacheInode;
 extern struct osi_file *afs_cacheInodep;
+extern int DCHash(struct VenusFid *fid, afs_int32 chunk);
+extern int DVHash(struct VenusFid *fid);
 extern void afs_dcacheInit(int afiles, int ablocks, int aDentries, int achunk,
                           int aflags);
 extern int afs_PutDCache(struct dcache *adc);
@@ -1053,6 +1055,8 @@ extern void afs_warnall(char *fmt, ...)
 #endif
 
 /* afs_vcache.c */
+extern int VCHash(struct VenusFid *fid);
+extern int VCHashV(struct VenusFid *fid);
 extern int afs_ShakeLooseVCaches(afs_int32 anumber);
 extern afs_int32 afs_maxvcount;
 extern afs_int32 afs_vcount;
index 63a0431..87ec2fc 100644 (file)
@@ -85,6 +85,25 @@ static struct afs_slotlist *afs_freeSlotList = NULL;
 /* Forward declarations */
 static afs_int32 afs_QueueVCB(struct vcache *avc, int *slept);
 
+
+/*
+ * The PFlush algorithm makes use of the fact that Fid.Unique is not used in
+ * below hash algorithms.  Change it if need be so that flushing algorithm
+ * doesn't move things from one hash chain to another.
+ */
+/* Don't hash on the cell; our callback-breaking code sometimes fails to compute
+ * the cell correctly, and only scans one hash bucket. */
+int VCHash(struct VenusFid *fid)
+{
+    return opr_jhash_int2(fid->Fid.Volume, fid->Fid.Vnode, 0) &
+       opr_jhash_mask(VCSIZEBITS);
+}
+/* Hash only on volume to speed up volume callbacks. */
+int VCHashV(struct VenusFid *fid)
+{
+    return opr_jhash_int(fid->Fid.Vnode, 0) & opr_jhash_mask(VCSIZEBITS);
+}
+
 /*!
  * Generate an index into the hash table for a given Fid.
  * \param fid