Dynamically size the pidhash hash table.

 init/main.c  |    4 +++-
 kernel/pid.c |   40 +++++++++++++++++++++++++++++-----------
 2 files changed, 32 insertions(+), 12 deletions(-)


diff -urpN wli-2.5.51-bk1-12/init/main.c wli-2.5.51-bk1-13/init/main.c
--- wli-2.5.51-bk1-12/init/main.c	2002-12-09 18:45:44.000000000 -0800
+++ wli-2.5.51-bk1-13/init/main.c	2002-12-12 22:13:31.000000000 -0800
@@ -68,6 +68,7 @@ extern void sysctl_init(void);
 extern void signals_init(void);
 extern void buffer_init(void);
 extern void pidhash_init(void);
+extern void pidmap_init(void);
 extern void pte_chain_init(void);
 extern void radix_tree_init(void);
 extern void free_initmem(void);
@@ -371,6 +372,7 @@ asmlinkage void __init start_kernel(void
 	extable_init();
 	rcu_init();
 	init_IRQ();
+	pidhash_init();
 	sched_init();
 	softirq_init();
 	time_init();
@@ -396,7 +398,7 @@ asmlinkage void __init start_kernel(void
 	page_address_init();
 	mem_init();
 	kmem_cache_sizes_init();
-	pidhash_init();
+	pidmap_init();
 	pgtable_cache_init();
 	pte_chain_init();
 	fork_init(num_physpages);
diff -urpN wli-2.5.51-bk1-12/kernel/pid.c wli-2.5.51-bk1-13/kernel/pid.c
--- wli-2.5.51-bk1-12/kernel/pid.c	2002-12-09 18:46:10.000000000 -0800
+++ wli-2.5.51-bk1-13/kernel/pid.c	2002-12-13 08:21:41.000000000 -0800
@@ -23,10 +23,11 @@
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/bootmem.h>
+#include <linux/hash.h>
 
-#define PIDHASH_SIZE 4096
-#define pid_hashfn(nr) ((nr >> 8) ^ nr) & (PIDHASH_SIZE - 1)
-static struct list_head pid_hash[PIDTYPE_MAX][PIDHASH_SIZE];
+#define pid_hashfn(nr) hash_long((unsigned long)nr, pidhash_shift)
+static struct list_head *pid_hash[PIDTYPE_MAX];
+static int pidhash_shift;
 
 int pid_max = PID_MAX_DEFAULT;
 int last_pid;
@@ -260,18 +261,35 @@ void switch_exec_pids(task_t *leader, ta
 
 void __init pidhash_init(void)
 {
-	int i, j;
+	int i, j, pidhash_size;
+
+	pidhash_shift = max(4, fls(max_pfn >> 6));
+	pidhash_shift = min(PAGE_SHIFT, pidhash_shift);
+	pidhash_size = 1 << pidhash_shift;
+
+	printk("PID hash table entries: %d (order %d: %d bytes)\n", pidhash_size, pidhash_shift, pidhash_size * sizeof(struct list_head));
+
+	for (i = 0; i < PIDTYPE_MAX; i++) {
+		pid_hash[i] = alloc_bootmem(pidhash_size * sizeof(struct list_head));
+		if (!pid_hash[i])
+			panic("Could not alloc pidhash!\n");
+		for (j = 0; j < pidhash_size; j++)
+			INIT_LIST_HEAD(&pid_hash[i][j]);
+	}
+}
+
+void __init pidmap_init(void)
+{
+	int i;
 
-	/*
-	 * Allocate PID 0, and hash it via all PID types:
-	 */
 	pidmap_array->page = (void *)get_zeroed_page(GFP_KERNEL);
 	set_bit(0, pidmap_array->page);
 	atomic_dec(&pidmap_array->nr_free);
 
-	for (i = 0; i < PIDTYPE_MAX; i++) {
-		for (j = 0; j < PIDHASH_SIZE; j++)
-			INIT_LIST_HEAD(&pid_hash[i][j]);
+	/*
+	 * Allocate PID 0, and hash it via all PID types:
+	 */
+
+	for (i = 0; i < PIDTYPE_MAX; i++)
 		attach_pid(current, i, 0);
-	}
 }