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 #include #include +#include -#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); - } }