diff -Nur linux-2.6.2-rc1/fs/dcache.c linux-2.6.2-rc1.ken/fs/dcache.c --- linux-2.6.2-rc1/fs/dcache.c 2004-01-20 19:49:25.000000000 -0800 +++ linux-2.6.2-rc1.ken/fs/dcache.c 2004-02-17 15:31:35.000000000 -0800 @@ -1527,6 +1527,16 @@ return ino; } +static __initdata unsigned long dhash_entries; +static int __init set_dhash_entries(char *str) +{ + if (!str) + return 0; + dhash_entries = simple_strtoul(str, &str, 0); + return 1; +} +__setup("dhash_entries=", set_dhash_entries); + static void __init dcache_init(unsigned long mempages) { struct hlist_head *d; @@ -1552,11 +1562,13 @@ set_shrinker(DEFAULT_SEEKS, shrink_dcache_memory); -#if PAGE_SHIFT < 13 - mempages >>= (13 - PAGE_SHIFT); -#endif - mempages *= sizeof(struct hlist_head); - for (order = 0; ((1UL << order) << PAGE_SHIFT) < mempages; order++) + if (!dhash_entries) { + dhash_entries = PAGE_SHIFT < 13 ? + mempages >> (13 - PAGE_SHIFT) : + mempages << (PAGE_SHIFT - 13); + } + dhash_entries *= sizeof(struct hlist_head); + for (order = 0; ((1UL << order) << PAGE_SHIFT) < dhash_entries; order++) ; do { diff -Nur linux-2.6.2-rc1/fs/inode.c linux-2.6.2-rc1.ken/fs/inode.c --- linux-2.6.2-rc1/fs/inode.c 2004-01-20 19:50:41.000000000 -0800 +++ linux-2.6.2-rc1.ken/fs/inode.c 2004-02-17 15:30:51.000000000 -0800 @@ -1327,6 +1327,16 @@ wake_up_all(wq); } +static __initdata unsigned long ihash_entries; +static int __init set_ihash_entries(char *str) +{ + if (!str) + return 0; + ihash_entries = simple_strtoul(str, &str, 0); + return 1; +} +__setup("ihash_entries=", set_ihash_entries); + /* * Initialize the waitqueues and inode hash table. */ @@ -1340,9 +1350,13 @@ for (i = 0; i < ARRAY_SIZE(i_wait_queue_heads); i++) init_waitqueue_head(&i_wait_queue_heads[i].wqh); - mempages >>= (14 - PAGE_SHIFT); - mempages *= sizeof(struct hlist_head); - for (order = 0; ((1UL << order) << PAGE_SHIFT) < mempages; order++) + if (!ihash_entries) { + ihash_entries = PAGE_SHIFT < 14 ? + mempages >> (14 - PAGE_SHIFT) : + mempages << (PAGE_SHIFT - 14); + } + ihash_entries *= sizeof(struct hlist_head); + for (order = 0; ((1UL << order) << PAGE_SHIFT) < ihash_entries; order++) ; do { diff -Nur linux-2.6.2-rc1/net/ipv4/route.c linux-2.6.2-rc1.ken/net/ipv4/route.c --- linux-2.6.2-rc1/net/ipv4/route.c 2004-01-20 19:50:41.000000000 -0800 +++ linux-2.6.2-rc1.ken/net/ipv4/route.c 2004-02-17 15:43:59.000000000 -0800 @@ -2717,6 +2717,16 @@ #endif /* CONFIG_PROC_FS */ #endif /* CONFIG_NET_CLS_ROUTE */ +static __initdata unsigned long rhash_entries; +static int __init set_rhash_entries(char *str) +{ + if (!str) + return 0; + rhash_entries = simple_strtoul(str, &str, 0); + return 1; +} +__setup("rhash_entries=", set_rhash_entries); + int __init ip_rt_init(void) { int i, order, goal, rc = 0; @@ -2742,8 +2752,10 @@ if (!ipv4_dst_ops.kmem_cachep) panic("IP: failed to allocate ip_dst_cache\n"); - goal = num_physpages >> (26 - PAGE_SHIFT); - + if (!rhash_entries) + goal = num_physpages >> (26 - PAGE_SHIFT); + else + goal = (rhash_entries * sizeof(struct rt_hash_bucket)) >> PAGE_SHIFT; for (order = 0; (1UL << order) < goal; order++) /* NOTHING */; diff -Nur linux-2.6.2-rc1/net/ipv4/tcp.c linux-2.6.2-rc1.ken/net/ipv4/tcp.c --- linux-2.6.2-rc1/net/ipv4/tcp.c 2004-01-20 19:49:36.000000000 -0800 +++ linux-2.6.2-rc1.ken/net/ipv4/tcp.c 2004-02-17 15:45:25.000000000 -0800 @@ -2569,6 +2569,16 @@ extern void __skb_cb_too_small_for_tcp(int, int); extern void tcpdiag_init(void); +static __initdata unsigned long thash_entries; +static int __init set_thash_entries(char *str) +{ + if (!str) + return 0; + thash_entries = simple_strtoul(str, &str, 0); + return 1; +} +__setup("thash_entries=", set_thash_entries); + void __init tcp_init(void) { struct sk_buff *skb = NULL; @@ -2610,6 +2620,8 @@ else goal = num_physpages >> (23 - PAGE_SHIFT); + if (thash_entries) + goal = (thash_entries * sizeof(struct tcp_ehash_bucket)) >> PAGE_SHIFT; for (order = 0; (1UL << order) < goal; order++) ; do {