patch-1.3.55 linux/include/linux/pagemap.h

Next file: linux/include/linux/sbpcd.h
Previous file: linux/include/linux/fdreg.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v1.3.54/linux/include/linux/pagemap.h linux/include/linux/pagemap.h
@@ -12,16 +12,29 @@
 	return PAGE_OFFSET + PAGE_SIZE*(page - mem_map);
 }
 
-#define PAGE_HASH_SIZE 257
+#define PAGE_HASH_BITS 10
+#define PAGE_HASH_SIZE (1 << PAGE_HASH_BITS)
+
 #define PAGE_AGE_VALUE 16
 
 extern unsigned long page_cache_size;
 extern struct page * page_hash_table[PAGE_HASH_SIZE];
 
+/*
+ * We use a power-of-two hash table to avoid a modulus,
+ * and get a reasonable hash by knowing roughly how the
+ * inode pointer and offsets are distributed (ie, we
+ * roughly know which bits are "significant")
+ */
 static inline unsigned long _page_hashfn(struct inode * inode, unsigned long offset)
 {
-	offset ^= (unsigned long) inode;
-	return offset % PAGE_HASH_SIZE;
+#define i (((unsigned long) inode)/sizeof(unsigned long))
+#define o (offset >> PAGE_SHIFT)
+#define s(x) ((x)+((x)>>PAGE_HASH_BITS))
+	return s(i+o) & (PAGE_HASH_SIZE-1);
+#undef i
+#undef o
+#undef s
 }
 
 #define page_hash(inode,offset) page_hash_table[_page_hashfn(inode,offset)]

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov with Sam's (original) version
of this