[patch] 2.2.14pre[12] dcache dynamic hash bugfix

Andrea Arcangeli (andrea@suse.de)
Fri, 29 Oct 1999 16:54:49 +0200 (CEST)


In 2.2.14pre[12] the dcache hash is allocated dynamically at boot (new
feature not yet present in 2.3.24).

But due to an obviously wrong buggy heuristic the current 2.2.14pre*
kernels are allocating a fixed amount of 2mbyte of ram (the maximal order
allowed by GFP) even on 4mbyte of ram machine. (just run dmesg | grep
DENTRY) This make the 2.2.14pre[12] kernels unusable on low memory
machines.

Also it doesn't worth to bloat the binary with static .data stuff that can
be dynamically set to zero at boot time.

I reimplemented the heuristic from scratch in my way. This is an userspace
simulation for the Alpha platform:

memory_size 512KB pages 64 order 0 hashsize 8KB entry 512
memory_size 1024KB pages 128 order 0 hashsize 8KB entry 512
memory_size 2048KB pages 256 order 0 hashsize 8KB entry 512
memory_size 4096KB pages 512 order 0 hashsize 8KB entry 512
memory_size 8192KB pages 1024 order 1 hashsize 16KB entry 1024
memory_size 16384KB pages 2048 order 2 hashsize 32KB entry 2048
memory_size 32768KB pages 4096 order 3 hashsize 64KB entry 4096
memory_size 65536KB pages 8192 order 4 hashsize 128KB entry 8192
memory_size 131072KB pages 16384 order 5 hashsize 256KB entry 16384
memory_size 262144KB pages 32768 order 6 hashsize 512KB entry 32768
memory_size 524288KB pages 65536 order 7 hashsize 1024KB entry 65536
memory_size 1048576KB pages 131072 order 8 hashsize 2048KB entry 131072

A lilttle explanation:

memory_size -> is the amount of memory available in the system
pages -> memory_size >> PAGE_SHIFT
order -> order used to alloc the hashtable via GFP
(GFP(order) will return 2**order free pages).
hashsize -> hashtable size (it's 2**order)
entry -> number of buckets in the hashtable

-------------------------------------------------------------------------
And this is the i386 simulation:

memory_size 512KB pages 128 order 0 hashsize 4KB entry 512
memory_size 1024KB pages 256 order 0 hashsize 4KB entry 512
memory_size 2048KB pages 512 order 0 hashsize 4KB entry 512
memory_size 4096KB pages 1024 order 0 hashsize 4KB entry 512
memory_size 8192KB pages 2048 order 1 hashsize 8KB entry 1024
memory_size 16384KB pages 4096 order 2 hashsize 16KB entry 2048
memory_size 32768KB pages 8192 order 3 hashsize 32KB entry 4096
memory_size 65536KB pages 16384 order 4 hashsize 64KB entry 8192
memory_size 131072KB pages 32768 order 5 hashsize 128KB entry 16384
memory_size 262144KB pages 65536 order 6 hashsize 256KB entry 32768
memory_size 524288KB pages 131072 order 7 hashsize 512KB entry 65536
memory_size 1048576KB pages 262144 order 8 hashsize 1024KB entry 131072
----------------------------------------------------------------------------

Here it is the fix that implements the heuristic simulated above against
2.2.14pre2:

--- 2.2.14pre2/fs/dcache.c Fri Oct 29 16:40:41 1999
+++ 2.2.14pre2-dhashfix/fs/dcache.c Fri Oct 29 16:43:05 1999
@@ -45,9 +45,9 @@
#define D_HASHBITS d_hash_shift
#define D_HASHMASK d_hash_mask

-static unsigned int d_hash_mask = 0;
-static unsigned int d_hash_shift = 0;
-static struct list_head *dentry_hashtable = NULL;
+static unsigned int d_hash_mask;
+static unsigned int d_hash_shift;
+static struct list_head *dentry_hashtable;
static LIST_HEAD(dentry_unused);

struct {
@@ -926,8 +926,9 @@
panic("Cannot create dentry cache");

memory_size = num_physpages << PAGE_SHIFT;
- for (order = 5; (1UL << order) < memory_size; order++)
- ;
+ memory_size >>= 13;
+ memory_size *= 2 * sizeof(void *);
+ for (order = 0; ((1UL << order) << PAGE_SHIFT) < memory_size; order++);

do {
unsigned long tmp;

Andrea

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/