diff options
author | Jan Beulich <JBeulich@novell.com> | 2009-09-21 20:03:07 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-22 10:17:38 -0400 |
commit | 2c85f51d222ccdd8c401d77a36b723a89156810d (patch) | |
tree | fb94c6ea243504043e434f0a7d26cfd4831b33a9 | |
parent | 3c1596efe167322dae87f8390d36f91ce2d7f936 (diff) |
mm: also use alloc_large_system_hash() for the PID hash table
This is being done by allowing boot time allocations to specify that they
may want a sub-page sized amount of memory.
Overall this seems more consistent with the other hash table allocations,
and allows making two supposedly mm-only variables really mm-only
(nr_{kernel,all}_pages).
Signed-off-by: Jan Beulich <jbeulich@novell.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Cc: Mel Gorman <mel@csn.ul.ie>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | include/linux/bootmem.h | 5 | ||||
-rw-r--r-- | kernel/pid.c | 15 | ||||
-rw-r--r-- | mm/page_alloc.c | 13 |
3 files changed, 16 insertions, 17 deletions
diff --git a/include/linux/bootmem.h b/include/linux/bootmem.h index bc3ab7073695..dd97fb8408a8 100644 --- a/include/linux/bootmem.h +++ b/include/linux/bootmem.h | |||
@@ -132,9 +132,6 @@ static inline void *alloc_remap(int nid, unsigned long size) | |||
132 | } | 132 | } |
133 | #endif /* CONFIG_HAVE_ARCH_ALLOC_REMAP */ | 133 | #endif /* CONFIG_HAVE_ARCH_ALLOC_REMAP */ |
134 | 134 | ||
135 | extern unsigned long __meminitdata nr_kernel_pages; | ||
136 | extern unsigned long __meminitdata nr_all_pages; | ||
137 | |||
138 | extern void *alloc_large_system_hash(const char *tablename, | 135 | extern void *alloc_large_system_hash(const char *tablename, |
139 | unsigned long bucketsize, | 136 | unsigned long bucketsize, |
140 | unsigned long numentries, | 137 | unsigned long numentries, |
@@ -145,6 +142,8 @@ extern void *alloc_large_system_hash(const char *tablename, | |||
145 | unsigned long limit); | 142 | unsigned long limit); |
146 | 143 | ||
147 | #define HASH_EARLY 0x00000001 /* Allocating during early boot? */ | 144 | #define HASH_EARLY 0x00000001 /* Allocating during early boot? */ |
145 | #define HASH_SMALL 0x00000002 /* sub-page allocation allowed, min | ||
146 | * shift passed via *_hash_shift */ | ||
148 | 147 | ||
149 | /* Only NUMA needs hash distribution. 64bit NUMA architectures have | 148 | /* Only NUMA needs hash distribution. 64bit NUMA architectures have |
150 | * sufficient vmalloc space. | 149 | * sufficient vmalloc space. |
diff --git a/kernel/pid.c b/kernel/pid.c index 31310b5d3f50..d3f722d20f9c 100644 --- a/kernel/pid.c +++ b/kernel/pid.c | |||
@@ -40,7 +40,7 @@ | |||
40 | #define pid_hashfn(nr, ns) \ | 40 | #define pid_hashfn(nr, ns) \ |
41 | hash_long((unsigned long)nr + (unsigned long)ns, pidhash_shift) | 41 | hash_long((unsigned long)nr + (unsigned long)ns, pidhash_shift) |
42 | static struct hlist_head *pid_hash; | 42 | static struct hlist_head *pid_hash; |
43 | static int pidhash_shift; | 43 | static unsigned int pidhash_shift = 4; |
44 | struct pid init_struct_pid = INIT_STRUCT_PID; | 44 | struct pid init_struct_pid = INIT_STRUCT_PID; |
45 | 45 | ||
46 | int pid_max = PID_MAX_DEFAULT; | 46 | int pid_max = PID_MAX_DEFAULT; |
@@ -499,19 +499,12 @@ struct pid *find_ge_pid(int nr, struct pid_namespace *ns) | |||
499 | void __init pidhash_init(void) | 499 | void __init pidhash_init(void) |
500 | { | 500 | { |
501 | int i, pidhash_size; | 501 | int i, pidhash_size; |
502 | unsigned long megabytes = nr_kernel_pages >> (20 - PAGE_SHIFT); | ||
503 | 502 | ||
504 | pidhash_shift = max(4, fls(megabytes * 4)); | 503 | pid_hash = alloc_large_system_hash("PID", sizeof(*pid_hash), 0, 18, |
505 | pidhash_shift = min(12, pidhash_shift); | 504 | HASH_EARLY | HASH_SMALL, |
505 | &pidhash_shift, NULL, 4096); | ||
506 | pidhash_size = 1 << pidhash_shift; | 506 | pidhash_size = 1 << pidhash_shift; |
507 | 507 | ||
508 | printk("PID hash table entries: %d (order: %d, %Zd bytes)\n", | ||
509 | pidhash_size, pidhash_shift, | ||
510 | pidhash_size * sizeof(struct hlist_head)); | ||
511 | |||
512 | pid_hash = alloc_bootmem(pidhash_size * sizeof(*(pid_hash))); | ||
513 | if (!pid_hash) | ||
514 | panic("Could not alloc pidhash!\n"); | ||
515 | for (i = 0; i < pidhash_size; i++) | 508 | for (i = 0; i < pidhash_size; i++) |
516 | INIT_HLIST_HEAD(&pid_hash[i]); | 509 | INIT_HLIST_HEAD(&pid_hash[i]); |
517 | } | 510 | } |
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 33b1a4762a7b..770f011e1c12 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -124,8 +124,8 @@ static char * const zone_names[MAX_NR_ZONES] = { | |||
124 | 124 | ||
125 | int min_free_kbytes = 1024; | 125 | int min_free_kbytes = 1024; |
126 | 126 | ||
127 | unsigned long __meminitdata nr_kernel_pages; | 127 | static unsigned long __meminitdata nr_kernel_pages; |
128 | unsigned long __meminitdata nr_all_pages; | 128 | static unsigned long __meminitdata nr_all_pages; |
129 | static unsigned long __meminitdata dma_reserve; | 129 | static unsigned long __meminitdata dma_reserve; |
130 | 130 | ||
131 | #ifdef CONFIG_ARCH_POPULATES_NODE_MAP | 131 | #ifdef CONFIG_ARCH_POPULATES_NODE_MAP |
@@ -4821,7 +4821,14 @@ void *__init alloc_large_system_hash(const char *tablename, | |||
4821 | numentries <<= (PAGE_SHIFT - scale); | 4821 | numentries <<= (PAGE_SHIFT - scale); |
4822 | 4822 | ||
4823 | /* Make sure we've got at least a 0-order allocation.. */ | 4823 | /* Make sure we've got at least a 0-order allocation.. */ |
4824 | if (unlikely((numentries * bucketsize) < PAGE_SIZE)) | 4824 | if (unlikely(flags & HASH_SMALL)) { |
4825 | /* Makes no sense without HASH_EARLY */ | ||
4826 | WARN_ON(!(flags & HASH_EARLY)); | ||
4827 | if (!(numentries >> *_hash_shift)) { | ||
4828 | numentries = 1UL << *_hash_shift; | ||
4829 | BUG_ON(!numentries); | ||
4830 | } | ||
4831 | } else if (unlikely((numentries * bucketsize) < PAGE_SIZE)) | ||
4825 | numentries = PAGE_SIZE / bucketsize; | 4832 | numentries = PAGE_SIZE / bucketsize; |
4826 | } | 4833 | } |
4827 | numentries = roundup_pow_of_two(numentries); | 4834 | numentries = roundup_pow_of_two(numentries); |