diff options
author | Bernhard Walle <bwalle@suse.de> | 2008-02-07 03:15:17 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2008-02-07 11:42:25 -0500 |
commit | 72a7fe3967dbf86cb34e24fbf1d957fe24d2f246 (patch) | |
tree | c19f7d0b530577359840e959cce204939caf0649 /mm | |
parent | 25fad945a7f7ff2cf06e437381c6a1121784dbd9 (diff) |
Introduce flags for reserve_bootmem()
This patchset adds a flags variable to reserve_bootmem() and uses the
BOOTMEM_EXCLUSIVE flag in crashkernel reservation code to detect collisions
between crashkernel area and already used memory.
This patch:
Change the reserve_bootmem() function to accept a new flag BOOTMEM_EXCLUSIVE.
If that flag is set, the function returns with -EBUSY if the memory already
has been reserved in the past. This is to avoid conflicts.
Because that code runs before SMP initialisation, there's no race condition
inside reserve_bootmem_core().
[akpm@linux-foundation.org: coding-style fixes]
[akpm@linux-foundation.org: fix powerpc build]
Signed-off-by: Bernhard Walle <bwalle@suse.de>
Cc: <linux-arch@vger.kernel.org>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Cc: Vivek Goyal <vgoyal@in.ibm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm')
-rw-r--r-- | mm/bootmem.c | 27 |
1 files changed, 21 insertions, 6 deletions
diff --git a/mm/bootmem.c b/mm/bootmem.c index 00a96970b237..f6ff4337b424 100644 --- a/mm/bootmem.c +++ b/mm/bootmem.c | |||
@@ -111,11 +111,12 @@ static unsigned long __init init_bootmem_core(pg_data_t *pgdat, | |||
111 | * might be used for boot-time allocations - or it might get added | 111 | * might be used for boot-time allocations - or it might get added |
112 | * to the free page pool later on. | 112 | * to the free page pool later on. |
113 | */ | 113 | */ |
114 | static void __init reserve_bootmem_core(bootmem_data_t *bdata, unsigned long addr, | 114 | static int __init reserve_bootmem_core(bootmem_data_t *bdata, |
115 | unsigned long size) | 115 | unsigned long addr, unsigned long size, int flags) |
116 | { | 116 | { |
117 | unsigned long sidx, eidx; | 117 | unsigned long sidx, eidx; |
118 | unsigned long i; | 118 | unsigned long i; |
119 | int ret; | ||
119 | 120 | ||
120 | /* | 121 | /* |
121 | * round up, partially reserved pages are considered | 122 | * round up, partially reserved pages are considered |
@@ -133,7 +134,20 @@ static void __init reserve_bootmem_core(bootmem_data_t *bdata, unsigned long add | |||
133 | #ifdef CONFIG_DEBUG_BOOTMEM | 134 | #ifdef CONFIG_DEBUG_BOOTMEM |
134 | printk("hm, page %08lx reserved twice.\n", i*PAGE_SIZE); | 135 | printk("hm, page %08lx reserved twice.\n", i*PAGE_SIZE); |
135 | #endif | 136 | #endif |
137 | if (flags & BOOTMEM_EXCLUSIVE) { | ||
138 | ret = -EBUSY; | ||
139 | goto err; | ||
140 | } | ||
136 | } | 141 | } |
142 | |||
143 | return 0; | ||
144 | |||
145 | err: | ||
146 | /* unreserve memory we accidentally reserved */ | ||
147 | for (i--; i >= sidx; i--) | ||
148 | clear_bit(i, bdata->node_bootmem_map); | ||
149 | |||
150 | return ret; | ||
137 | } | 151 | } |
138 | 152 | ||
139 | static void __init free_bootmem_core(bootmem_data_t *bdata, unsigned long addr, | 153 | static void __init free_bootmem_core(bootmem_data_t *bdata, unsigned long addr, |
@@ -374,9 +388,9 @@ unsigned long __init init_bootmem_node(pg_data_t *pgdat, unsigned long freepfn, | |||
374 | } | 388 | } |
375 | 389 | ||
376 | void __init reserve_bootmem_node(pg_data_t *pgdat, unsigned long physaddr, | 390 | void __init reserve_bootmem_node(pg_data_t *pgdat, unsigned long physaddr, |
377 | unsigned long size) | 391 | unsigned long size, int flags) |
378 | { | 392 | { |
379 | reserve_bootmem_core(pgdat->bdata, physaddr, size); | 393 | reserve_bootmem_core(pgdat->bdata, physaddr, size, flags); |
380 | } | 394 | } |
381 | 395 | ||
382 | void __init free_bootmem_node(pg_data_t *pgdat, unsigned long physaddr, | 396 | void __init free_bootmem_node(pg_data_t *pgdat, unsigned long physaddr, |
@@ -398,9 +412,10 @@ unsigned long __init init_bootmem(unsigned long start, unsigned long pages) | |||
398 | } | 412 | } |
399 | 413 | ||
400 | #ifndef CONFIG_HAVE_ARCH_BOOTMEM_NODE | 414 | #ifndef CONFIG_HAVE_ARCH_BOOTMEM_NODE |
401 | void __init reserve_bootmem(unsigned long addr, unsigned long size) | 415 | int __init reserve_bootmem(unsigned long addr, unsigned long size, |
416 | int flags) | ||
402 | { | 417 | { |
403 | reserve_bootmem_core(NODE_DATA(0)->bdata, addr, size); | 418 | return reserve_bootmem_core(NODE_DATA(0)->bdata, addr, size, flags); |
404 | } | 419 | } |
405 | #endif /* !CONFIG_HAVE_ARCH_BOOTMEM_NODE */ | 420 | #endif /* !CONFIG_HAVE_ARCH_BOOTMEM_NODE */ |
406 | 421 | ||