diff options
| author | Bernhard Walle <bwalle@suse.de> | 2008-02-07 00:15:17 -0800 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2008-02-07 08:42:25 -0800 | 
| commit | 72a7fe3967dbf86cb34e24fbf1d957fe24d2f246 (patch) | |
| tree | c19f7d0b530577359840e959cce204939caf0649 /mm/bootmem.c | |
| parent | 25fad945a7f7ff2cf06e437381c6a1121784dbd9 (diff) | |
| download | olio-linux-3.10-72a7fe3967dbf86cb34e24fbf1d957fe24d2f246.tar.xz olio-linux-3.10-72a7fe3967dbf86cb34e24fbf1d957fe24d2f246.zip  | |
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/bootmem.c')
| -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 00a96970b23..f6ff4337b42 100644 --- a/mm/bootmem.c +++ b/mm/bootmem.c @@ -111,11 +111,12 @@ static unsigned long __init init_bootmem_core(pg_data_t *pgdat,   * might be used for boot-time allocations - or it might get added   * to the free page pool later on.   */ -static void __init reserve_bootmem_core(bootmem_data_t *bdata, unsigned long addr, -					unsigned long size) +static int __init reserve_bootmem_core(bootmem_data_t *bdata, +			unsigned long addr, unsigned long size, int flags)  {  	unsigned long sidx, eidx;  	unsigned long i; +	int ret;  	/*  	 * round up, partially reserved pages are considered @@ -133,7 +134,20 @@ static void __init reserve_bootmem_core(bootmem_data_t *bdata, unsigned long add  #ifdef CONFIG_DEBUG_BOOTMEM  			printk("hm, page %08lx reserved twice.\n", i*PAGE_SIZE);  #endif +			if (flags & BOOTMEM_EXCLUSIVE) { +				ret = -EBUSY; +				goto err; +			}  		} + +	return 0; + +err: +	/* unreserve memory we accidentally reserved */ +	for (i--; i >= sidx; i--) +		clear_bit(i, bdata->node_bootmem_map); + +	return ret;  }  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,  }  void __init reserve_bootmem_node(pg_data_t *pgdat, unsigned long physaddr, -				 unsigned long size) +				 unsigned long size, int flags)  { -	reserve_bootmem_core(pgdat->bdata, physaddr, size); +	reserve_bootmem_core(pgdat->bdata, physaddr, size, flags);  }  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)  }  #ifndef CONFIG_HAVE_ARCH_BOOTMEM_NODE -void __init reserve_bootmem(unsigned long addr, unsigned long size) +int __init reserve_bootmem(unsigned long addr, unsigned long size, +			    int flags)  { -	reserve_bootmem_core(NODE_DATA(0)->bdata, addr, size); +	return reserve_bootmem_core(NODE_DATA(0)->bdata, addr, size, flags);  }  #endif /* !CONFIG_HAVE_ARCH_BOOTMEM_NODE */  |