Blame view

mm/memblock.c 58 KB
2874c5fd2   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-or-later
95f72d1ed   Yinghai Lu   lmb: rename to me...
2
3
4
5
6
  /*
   * Procedures for maintaining information about logical memory blocks.
   *
   * Peter Bergner, IBM Corp.	June 2001.
   * Copyright (C) 2001 Peter Bergner.
95f72d1ed   Yinghai Lu   lmb: rename to me...
7
8
9
   */
  
  #include <linux/kernel.h>
142b45a72   Benjamin Herrenschmidt   memblock: Add arr...
10
  #include <linux/slab.h>
95f72d1ed   Yinghai Lu   lmb: rename to me...
11
12
  #include <linux/init.h>
  #include <linux/bitops.h>
449e8df39   Benjamin Herrenschmidt   memblock: Add deb...
13
  #include <linux/poison.h>
c196f76fd   Benjamin Herrenschmidt   memblock: NUMA al...
14
  #include <linux/pfn.h>
6d03b885f   Benjamin Herrenschmidt   memblock: Add deb...
15
  #include <linux/debugfs.h>
514c60324   Randy Dunlap   headers: untangle...
16
  #include <linux/kmemleak.h>
6d03b885f   Benjamin Herrenschmidt   memblock: Add deb...
17
  #include <linux/seq_file.h>
95f72d1ed   Yinghai Lu   lmb: rename to me...
18
  #include <linux/memblock.h>
c4c5ad6b3   Christoph Hellwig   memblock: include...
19
  #include <asm/sections.h>
26f09e9b3   Santosh Shilimkar   mm/memblock: add ...
20
21
22
  #include <linux/io.h>
  
  #include "internal.h"
79442ed18   Tang Chen   mm/memblock.c: in...
23

8a5b403d7   Ard Biesheuvel   arm64, mm, efi: A...
24
25
26
27
28
29
  #define INIT_MEMBLOCK_REGIONS			128
  #define INIT_PHYSMEM_REGIONS			4
  
  #ifndef INIT_MEMBLOCK_RESERVED_REGIONS
  # define INIT_MEMBLOCK_RESERVED_REGIONS		INIT_MEMBLOCK_REGIONS
  #endif
3e039c5c0   Mike Rapoport   docs/mm: memblock...
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
  /**
   * DOC: memblock overview
   *
   * Memblock is a method of managing memory regions during the early
   * boot period when the usual kernel memory allocators are not up and
   * running.
   *
   * Memblock views the system memory as collections of contiguous
   * regions. There are several types of these collections:
   *
   * * ``memory`` - describes the physical memory available to the
   *   kernel; this may differ from the actual physical memory installed
   *   in the system, for instance when the memory is restricted with
   *   ``mem=`` command line parameter
   * * ``reserved`` - describes the regions that were allocated
776499058   David Hildenbrand   mm/memblock: expo...
45
46
47
   * * ``physmem`` - describes the actual physical memory available during
   *   boot regardless of the possible restrictions and memory hot(un)plug;
   *   the ``physmem`` type is only available on some architectures.
3e039c5c0   Mike Rapoport   docs/mm: memblock...
48
   *
9303c9d5e   Mauro Carvalho Chehab   docs: get rid of ...
49
   * Each region is represented by struct memblock_region that
3e039c5c0   Mike Rapoport   docs/mm: memblock...
50
   * defines the region extents, its attributes and NUMA node id on NUMA
1bf162e44   Mauro Carvalho Chehab   memblock: get rid...
51
52
   * systems. Every memory type is described by the struct memblock_type
   * which contains an array of memory regions along with
776499058   David Hildenbrand   mm/memblock: expo...
53
   * the allocator metadata. The "memory" and "reserved" types are nicely
9303c9d5e   Mauro Carvalho Chehab   docs: get rid of ...
54
   * wrapped with struct memblock. This structure is statically
776499058   David Hildenbrand   mm/memblock: expo...
55
56
57
58
   * initialized at build time. The region arrays are initially sized to
   * %INIT_MEMBLOCK_REGIONS for "memory" and %INIT_MEMBLOCK_RESERVED_REGIONS
   * for "reserved". The region array for "physmem" is initially sized to
   * %INIT_PHYSMEM_REGIONS.
6e5af9a8e   Cao jin   mm/memblock.c: cl...
59
60
61
62
   * The memblock_allow_resize() enables automatic resizing of the region
   * arrays during addition of new regions. This feature should be used
   * with care so that memory allocated for the region array will not
   * overlap with areas that should be reserved, for example initrd.
3e039c5c0   Mike Rapoport   docs/mm: memblock...
63
64
   *
   * The early architecture setup should tell memblock what the physical
6e5af9a8e   Cao jin   mm/memblock.c: cl...
65
66
67
68
69
70
   * memory layout is by using memblock_add() or memblock_add_node()
   * functions. The first function does not assign the region to a NUMA
   * node and it is appropriate for UMA systems. Yet, it is possible to
   * use it on NUMA systems as well and assign the region to a NUMA node
   * later in the setup process using memblock_set_node(). The
   * memblock_add_node() performs such an assignment directly.
3e039c5c0   Mike Rapoport   docs/mm: memblock...
71
   *
a2974133b   Mike Rapoport   mm: memblock: upd...
72
73
74
   * Once memblock is setup the memory can be allocated using one of the
   * API variants:
   *
6e5af9a8e   Cao jin   mm/memblock.c: cl...
75
76
77
78
   * * memblock_phys_alloc*() - these functions return the **physical**
   *   address of the allocated memory
   * * memblock_alloc*() - these functions return the **virtual** address
   *   of the allocated memory.
a2974133b   Mike Rapoport   mm: memblock: upd...
79
   *
df1758d9f   Ethon Paul   mm/memblock: fix ...
80
   * Note, that both API variants use implicit assumptions about allowed
a2974133b   Mike Rapoport   mm: memblock: upd...
81
   * memory ranges and the fallback methods. Consult the documentation
6e5af9a8e   Cao jin   mm/memblock.c: cl...
82
83
   * of memblock_alloc_internal() and memblock_alloc_range_nid()
   * functions for more elaborate description.
3e039c5c0   Mike Rapoport   docs/mm: memblock...
84
   *
6e5af9a8e   Cao jin   mm/memblock.c: cl...
85
86
   * As the system boot progresses, the architecture specific mem_init()
   * function frees all the memory to the buddy page allocator.
3e039c5c0   Mike Rapoport   docs/mm: memblock...
87
   *
6e5af9a8e   Cao jin   mm/memblock.c: cl...
88
   * Unless an architecture enables %CONFIG_ARCH_KEEP_MEMBLOCK, the
776499058   David Hildenbrand   mm/memblock: expo...
89
90
   * memblock data structures (except "physmem") will be discarded after the
   * system initialization completes.
3e039c5c0   Mike Rapoport   docs/mm: memblock...
91
   */
bda49a811   Mike Rapoport   mm: remove nobootmem
92
93
94
95
96
97
98
99
100
  #ifndef CONFIG_NEED_MULTIPLE_NODES
  struct pglist_data __refdata contig_page_data;
  EXPORT_SYMBOL(contig_page_data);
  #endif
  
  unsigned long max_low_pfn;
  unsigned long min_low_pfn;
  unsigned long max_pfn;
  unsigned long long max_possible_pfn;
fe091c208   Tejun Heo   memblock: Kill me...
101
  static struct memblock_region memblock_memory_init_regions[INIT_MEMBLOCK_REGIONS] __initdata_memblock;
8a5b403d7   Ard Biesheuvel   arm64, mm, efi: A...
102
  static struct memblock_region memblock_reserved_init_regions[INIT_MEMBLOCK_RESERVED_REGIONS] __initdata_memblock;
70210ed95   Philipp Hachtmann   mm/memblock: add ...
103
  #ifdef CONFIG_HAVE_MEMBLOCK_PHYS_MAP
776499058   David Hildenbrand   mm/memblock: expo...
104
  static struct memblock_region memblock_physmem_init_regions[INIT_PHYSMEM_REGIONS];
70210ed95   Philipp Hachtmann   mm/memblock: add ...
105
  #endif
fe091c208   Tejun Heo   memblock: Kill me...
106
107
108
109
110
  
  struct memblock memblock __initdata_memblock = {
  	.memory.regions		= memblock_memory_init_regions,
  	.memory.cnt		= 1,	/* empty dummy entry */
  	.memory.max		= INIT_MEMBLOCK_REGIONS,
0262d9c84   Heiko Carstens   memblock: embed m...
111
  	.memory.name		= "memory",
fe091c208   Tejun Heo   memblock: Kill me...
112
113
114
  
  	.reserved.regions	= memblock_reserved_init_regions,
  	.reserved.cnt		= 1,	/* empty dummy entry */
8a5b403d7   Ard Biesheuvel   arm64, mm, efi: A...
115
  	.reserved.max		= INIT_MEMBLOCK_RESERVED_REGIONS,
0262d9c84   Heiko Carstens   memblock: embed m...
116
  	.reserved.name		= "reserved",
fe091c208   Tejun Heo   memblock: Kill me...
117

79442ed18   Tang Chen   mm/memblock.c: in...
118
  	.bottom_up		= false,
fe091c208   Tejun Heo   memblock: Kill me...
119
120
  	.current_limit		= MEMBLOCK_ALLOC_ANYWHERE,
  };
95f72d1ed   Yinghai Lu   lmb: rename to me...
121

776499058   David Hildenbrand   mm/memblock: expo...
122
123
124
125
126
127
128
129
  #ifdef CONFIG_HAVE_MEMBLOCK_PHYS_MAP
  struct memblock_type physmem = {
  	.regions		= memblock_physmem_init_regions,
  	.cnt			= 1,	/* empty dummy entry */
  	.max			= INIT_PHYSMEM_REGIONS,
  	.name			= "physmem",
  };
  #endif
9f3d5eaa3   Mike Rapoport   memblock: impleme...
130
131
132
133
134
135
136
  /*
   * keep a pointer to &memblock.memory in the text section to use it in
   * __next_mem_range() and its helpers.
   *  For architectures that do not keep memblock data after init, this
   * pointer will be reset to NULL at memblock_discard()
   */
  static __refdata struct memblock_type *memblock_memory = &memblock.memory;
cd991db8d   Mike Rapoport   memblock: make fo...
137
138
139
140
  #define for_each_memblock_type(i, memblock_type, rgn)			\
  	for (i = 0, rgn = &memblock_type->regions[0];			\
  	     i < memblock_type->cnt;					\
  	     i++, rgn = &memblock_type->regions[i])
87c55870f   Mike Rapoport   memblock: make me...
141
142
143
144
145
146
147
  #define memblock_dbg(fmt, ...)						\
  	do {								\
  		if (memblock_debug)					\
  			pr_info(fmt, ##__VA_ARGS__);			\
  	} while (0)
  
  static int memblock_debug __initdata_memblock;
a3f5bafcc   Tony Luck   mm/memblock: allo...
148
  static bool system_has_some_mirror __initdata_memblock = false;
1aadc0560   Tejun Heo   memblock: s/membl...
149
  static int memblock_can_resize __initdata_memblock;
181eb3942   Gavin Shan   mm/memblock: fix ...
150
151
  static int memblock_memory_in_slab __initdata_memblock = 0;
  static int memblock_reserved_in_slab __initdata_memblock = 0;
95f72d1ed   Yinghai Lu   lmb: rename to me...
152

c366ea89f   Mike Rapoport   memblock: make me...
153
  static enum memblock_flags __init_memblock choose_memblock_flags(void)
a3f5bafcc   Tony Luck   mm/memblock: allo...
154
155
156
  {
  	return system_has_some_mirror ? MEMBLOCK_MIRROR : MEMBLOCK_NONE;
  }
eb18f1b5b   Tejun Heo   memblock: Make me...
157
158
159
  /* adjust *@size so that (@base + *@size) doesn't overflow, return new size */
  static inline phys_addr_t memblock_cap_size(phys_addr_t base, phys_addr_t *size)
  {
1c4bc43dd   Stefan Agner   mm/memblock: intr...
160
  	return *size = min(*size, PHYS_ADDR_MAX - base);
eb18f1b5b   Tejun Heo   memblock: Make me...
161
  }
6ed311b28   Benjamin Herrenschmidt   memblock: Move fu...
162
163
164
  /*
   * Address comparison utilities
   */
10d064398   Yinghai Lu   memblock: Option ...
165
  static unsigned long __init_memblock memblock_addrs_overlap(phys_addr_t base1, phys_addr_t size1,
2898cc4cd   Benjamin Herrenschmidt   memblock: Change ...
166
  				       phys_addr_t base2, phys_addr_t size2)
95f72d1ed   Yinghai Lu   lmb: rename to me...
167
168
169
  {
  	return ((base1 < (base2 + size2)) && (base2 < (base1 + size1)));
  }
95cf82ecc   Tang Chen   mem-hotplug: hand...
170
  bool __init_memblock memblock_overlaps_region(struct memblock_type *type,
2d7d3eb2b   H Hartley Sweeten   mm/memblock.c: qu...
171
  					phys_addr_t base, phys_addr_t size)
6ed311b28   Benjamin Herrenschmidt   memblock: Move fu...
172
173
  {
  	unsigned long i;
f14516fbf   Alexander Kuleshov   mm/memblock: remo...
174
175
176
  	for (i = 0; i < type->cnt; i++)
  		if (memblock_addrs_overlap(base, size, type->regions[i].base,
  					   type->regions[i].size))
6ed311b28   Benjamin Herrenschmidt   memblock: Move fu...
177
  			break;
c5c5c9d10   Tang Chen   mm/memblock.c: ma...
178
  	return i < type->cnt;
6ed311b28   Benjamin Herrenschmidt   memblock: Move fu...
179
  }
47cec4432   Mike Rapoport   docs/mm: memblock...
180
  /**
79442ed18   Tang Chen   mm/memblock.c: in...
181
182
   * __memblock_find_range_bottom_up - find free area utility in bottom-up
   * @start: start of candidate range
47cec4432   Mike Rapoport   docs/mm: memblock...
183
184
   * @end: end of candidate range, can be %MEMBLOCK_ALLOC_ANYWHERE or
   *       %MEMBLOCK_ALLOC_ACCESSIBLE
79442ed18   Tang Chen   mm/memblock.c: in...
185
186
   * @size: size of free area to find
   * @align: alignment of free area to find
b11542335   Grygorii Strashko   mm/memblock: swit...
187
   * @nid: nid of the free area to find, %NUMA_NO_NODE for any node
fc6daaf93   Tony Luck   mm/memblock: add ...
188
   * @flags: pick from blocks based on memory attributes
79442ed18   Tang Chen   mm/memblock.c: in...
189
190
191
   *
   * Utility called from memblock_find_in_range_node(), find free area bottom-up.
   *
47cec4432   Mike Rapoport   docs/mm: memblock...
192
   * Return:
79442ed18   Tang Chen   mm/memblock.c: in...
193
194
195
196
   * Found address on success, 0 on failure.
   */
  static phys_addr_t __init_memblock
  __memblock_find_range_bottom_up(phys_addr_t start, phys_addr_t end,
fc6daaf93   Tony Luck   mm/memblock: add ...
197
  				phys_addr_t size, phys_addr_t align, int nid,
e1720fee2   Mike Rapoport   mm/memblock: add ...
198
  				enum memblock_flags flags)
79442ed18   Tang Chen   mm/memblock.c: in...
199
200
201
  {
  	phys_addr_t this_start, this_end, cand;
  	u64 i;
fc6daaf93   Tony Luck   mm/memblock: add ...
202
  	for_each_free_mem_range(i, nid, flags, &this_start, &this_end, NULL) {
79442ed18   Tang Chen   mm/memblock.c: in...
203
204
205
206
207
208
209
210
211
212
  		this_start = clamp(this_start, start, end);
  		this_end = clamp(this_end, start, end);
  
  		cand = round_up(this_start, align);
  		if (cand < this_end && this_end - cand >= size)
  			return cand;
  	}
  
  	return 0;
  }
7bd0b0f0d   Tejun Heo   memblock: Reimple...
213
  /**
1402899e4   Tang Chen   mm/memblock.c: fa...
214
   * __memblock_find_range_top_down - find free area utility, in top-down
7bd0b0f0d   Tejun Heo   memblock: Reimple...
215
   * @start: start of candidate range
47cec4432   Mike Rapoport   docs/mm: memblock...
216
217
   * @end: end of candidate range, can be %MEMBLOCK_ALLOC_ANYWHERE or
   *       %MEMBLOCK_ALLOC_ACCESSIBLE
7bd0b0f0d   Tejun Heo   memblock: Reimple...
218
219
   * @size: size of free area to find
   * @align: alignment of free area to find
b11542335   Grygorii Strashko   mm/memblock: swit...
220
   * @nid: nid of the free area to find, %NUMA_NO_NODE for any node
fc6daaf93   Tony Luck   mm/memblock: add ...
221
   * @flags: pick from blocks based on memory attributes
7bd0b0f0d   Tejun Heo   memblock: Reimple...
222
   *
1402899e4   Tang Chen   mm/memblock.c: fa...
223
   * Utility called from memblock_find_in_range_node(), find free area top-down.
7bd0b0f0d   Tejun Heo   memblock: Reimple...
224
   *
47cec4432   Mike Rapoport   docs/mm: memblock...
225
   * Return:
79442ed18   Tang Chen   mm/memblock.c: in...
226
   * Found address on success, 0 on failure.
6ed311b28   Benjamin Herrenschmidt   memblock: Move fu...
227
   */
1402899e4   Tang Chen   mm/memblock.c: fa...
228
229
  static phys_addr_t __init_memblock
  __memblock_find_range_top_down(phys_addr_t start, phys_addr_t end,
fc6daaf93   Tony Luck   mm/memblock: add ...
230
  			       phys_addr_t size, phys_addr_t align, int nid,
e1720fee2   Mike Rapoport   mm/memblock: add ...
231
  			       enum memblock_flags flags)
f7210e6c4   Tang Chen   mm/memblock.c: us...
232
233
234
  {
  	phys_addr_t this_start, this_end, cand;
  	u64 i;
fc6daaf93   Tony Luck   mm/memblock: add ...
235
236
  	for_each_free_mem_range_reverse(i, nid, flags, &this_start, &this_end,
  					NULL) {
f7210e6c4   Tang Chen   mm/memblock.c: us...
237
238
239
240
241
242
243
244
245
246
  		this_start = clamp(this_start, start, end);
  		this_end = clamp(this_end, start, end);
  
  		if (this_end < size)
  			continue;
  
  		cand = round_down(this_end - size, align);
  		if (cand >= this_start)
  			return cand;
  	}
1402899e4   Tang Chen   mm/memblock.c: fa...
247

f7210e6c4   Tang Chen   mm/memblock.c: us...
248
249
  	return 0;
  }
6ed311b28   Benjamin Herrenschmidt   memblock: Move fu...
250

7bd0b0f0d   Tejun Heo   memblock: Reimple...
251
  /**
1402899e4   Tang Chen   mm/memblock.c: fa...
252
   * memblock_find_in_range_node - find free area in given range and node
1402899e4   Tang Chen   mm/memblock.c: fa...
253
254
   * @size: size of free area to find
   * @align: alignment of free area to find
87029ee93   Grygorii Strashko   mm/memblock: reor...
255
   * @start: start of candidate range
47cec4432   Mike Rapoport   docs/mm: memblock...
256
257
   * @end: end of candidate range, can be %MEMBLOCK_ALLOC_ANYWHERE or
   *       %MEMBLOCK_ALLOC_ACCESSIBLE
b11542335   Grygorii Strashko   mm/memblock: swit...
258
   * @nid: nid of the free area to find, %NUMA_NO_NODE for any node
fc6daaf93   Tony Luck   mm/memblock: add ...
259
   * @flags: pick from blocks based on memory attributes
1402899e4   Tang Chen   mm/memblock.c: fa...
260
261
262
   *
   * Find @size free area aligned to @align in the specified range and node.
   *
79442ed18   Tang Chen   mm/memblock.c: in...
263
264
265
266
267
268
269
270
   * When allocation direction is bottom-up, the @start should be greater
   * than the end of the kernel image. Otherwise, it will be trimmed. The
   * reason is that we want the bottom-up allocation just near the kernel
   * image so it is highly likely that the allocated memory and the kernel
   * will reside in the same node.
   *
   * If bottom-up allocation failed, will try to allocate memory top-down.
   *
47cec4432   Mike Rapoport   docs/mm: memblock...
271
   * Return:
79442ed18   Tang Chen   mm/memblock.c: in...
272
   * Found address on success, 0 on failure.
1402899e4   Tang Chen   mm/memblock.c: fa...
273
   */
c366ea89f   Mike Rapoport   memblock: make me...
274
  static phys_addr_t __init_memblock memblock_find_in_range_node(phys_addr_t size,
87029ee93   Grygorii Strashko   mm/memblock: reor...
275
  					phys_addr_t align, phys_addr_t start,
e1720fee2   Mike Rapoport   mm/memblock: add ...
276
277
  					phys_addr_t end, int nid,
  					enum memblock_flags flags)
1402899e4   Tang Chen   mm/memblock.c: fa...
278
  {
0cfb8f0c3   Tang Chen   memblock, memhotp...
279
  	phys_addr_t kernel_end, ret;
79442ed18   Tang Chen   mm/memblock.c: in...
280

1402899e4   Tang Chen   mm/memblock.c: fa...
281
  	/* pump up @end */
fed84c785   Qian Cai   mm/memblock.c: sk...
282
283
  	if (end == MEMBLOCK_ALLOC_ACCESSIBLE ||
  	    end == MEMBLOCK_ALLOC_KASAN)
1402899e4   Tang Chen   mm/memblock.c: fa...
284
285
286
287
288
  		end = memblock.current_limit;
  
  	/* avoid allocating the first page */
  	start = max_t(phys_addr_t, start, PAGE_SIZE);
  	end = max(start, end);
79442ed18   Tang Chen   mm/memblock.c: in...
289
290
291
292
293
294
295
296
297
298
299
300
301
302
  	kernel_end = __pa_symbol(_end);
  
  	/*
  	 * try bottom-up allocation only when bottom-up mode
  	 * is set and @end is above the kernel image.
  	 */
  	if (memblock_bottom_up() && end > kernel_end) {
  		phys_addr_t bottom_up_start;
  
  		/* make sure we will allocate above the kernel */
  		bottom_up_start = max(start, kernel_end);
  
  		/* ok, try bottom-up allocation first */
  		ret = __memblock_find_range_bottom_up(bottom_up_start, end,
fc6daaf93   Tony Luck   mm/memblock: add ...
303
  						      size, align, nid, flags);
79442ed18   Tang Chen   mm/memblock.c: in...
304
305
306
307
308
309
310
311
312
313
314
315
316
  		if (ret)
  			return ret;
  
  		/*
  		 * we always limit bottom-up allocation above the kernel,
  		 * but top-down allocation doesn't have the limit, so
  		 * retrying top-down allocation may succeed when bottom-up
  		 * allocation failed.
  		 *
  		 * bottom-up allocation is expected to be fail very rarely,
  		 * so we use WARN_ONCE() here to see the stack trace if
  		 * fail happens.
  		 */
e3d301cae   Michal Hocko   mm/memblock.c: do...
317
318
319
  		WARN_ONCE(IS_ENABLED(CONFIG_MEMORY_HOTREMOVE),
  			  "memblock: bottom-up allocation failed, memory hotremove may be affected
  ");
79442ed18   Tang Chen   mm/memblock.c: in...
320
  	}
1402899e4   Tang Chen   mm/memblock.c: fa...
321

fc6daaf93   Tony Luck   mm/memblock: add ...
322
323
  	return __memblock_find_range_top_down(start, end, size, align, nid,
  					      flags);
1402899e4   Tang Chen   mm/memblock.c: fa...
324
325
326
  }
  
  /**
7bd0b0f0d   Tejun Heo   memblock: Reimple...
327
328
   * memblock_find_in_range - find free area in given range
   * @start: start of candidate range
47cec4432   Mike Rapoport   docs/mm: memblock...
329
330
   * @end: end of candidate range, can be %MEMBLOCK_ALLOC_ANYWHERE or
   *       %MEMBLOCK_ALLOC_ACCESSIBLE
7bd0b0f0d   Tejun Heo   memblock: Reimple...
331
332
333
334
335
   * @size: size of free area to find
   * @align: alignment of free area to find
   *
   * Find @size free area aligned to @align in the specified range.
   *
47cec4432   Mike Rapoport   docs/mm: memblock...
336
   * Return:
79442ed18   Tang Chen   mm/memblock.c: in...
337
   * Found address on success, 0 on failure.
fc769a8e7   Tejun Heo   memblock: Replace...
338
   */
7bd0b0f0d   Tejun Heo   memblock: Reimple...
339
340
341
  phys_addr_t __init_memblock memblock_find_in_range(phys_addr_t start,
  					phys_addr_t end, phys_addr_t size,
  					phys_addr_t align)
6ed311b28   Benjamin Herrenschmidt   memblock: Move fu...
342
  {
a3f5bafcc   Tony Luck   mm/memblock: allo...
343
  	phys_addr_t ret;
e1720fee2   Mike Rapoport   mm/memblock: add ...
344
  	enum memblock_flags flags = choose_memblock_flags();
a3f5bafcc   Tony Luck   mm/memblock: allo...
345
346
347
348
349
350
351
352
353
354
355
356
357
358
  
  again:
  	ret = memblock_find_in_range_node(size, align, start, end,
  					    NUMA_NO_NODE, flags);
  
  	if (!ret && (flags & MEMBLOCK_MIRROR)) {
  		pr_warn("Could not allocate %pap bytes of mirrored memory
  ",
  			&size);
  		flags &= ~MEMBLOCK_MIRROR;
  		goto again;
  	}
  
  	return ret;
6ed311b28   Benjamin Herrenschmidt   memblock: Move fu...
359
  }
10d064398   Yinghai Lu   memblock: Option ...
360
  static void __init_memblock memblock_remove_region(struct memblock_type *type, unsigned long r)
95f72d1ed   Yinghai Lu   lmb: rename to me...
361
  {
1440c4e2c   Tejun Heo   memblock: Track t...
362
  	type->total_size -= type->regions[r].size;
7c0caeb86   Tejun Heo   memblock: Add opt...
363
364
  	memmove(&type->regions[r], &type->regions[r + 1],
  		(type->cnt - (r + 1)) * sizeof(type->regions[r]));
e3239ff92   Benjamin Herrenschmidt   memblock: Rename ...
365
  	type->cnt--;
95f72d1ed   Yinghai Lu   lmb: rename to me...
366

8f7a66051   Benjamin Herrenschmidt   mm/memblock: prop...
367
368
  	/* Special case for empty arrays */
  	if (type->cnt == 0) {
1440c4e2c   Tejun Heo   memblock: Track t...
369
  		WARN_ON(type->total_size != 0);
8f7a66051   Benjamin Herrenschmidt   mm/memblock: prop...
370
371
372
  		type->cnt = 1;
  		type->regions[0].base = 0;
  		type->regions[0].size = 0;
66a207572   Tang Chen   memblock, numa: i...
373
  		type->regions[0].flags = 0;
7c0caeb86   Tejun Heo   memblock: Add opt...
374
  		memblock_set_region_node(&type->regions[0], MAX_NUMNODES);
8f7a66051   Benjamin Herrenschmidt   mm/memblock: prop...
375
  	}
95f72d1ed   Yinghai Lu   lmb: rename to me...
376
  }
350e88bad   Mike Rapoport   mm: memblock: mak...
377
  #ifndef CONFIG_ARCH_KEEP_MEMBLOCK
3010f8765   Pavel Tatashin   mm: discard membl...
378
  /**
47cec4432   Mike Rapoport   docs/mm: memblock...
379
   * memblock_discard - discard memory and reserved arrays if they were allocated
3010f8765   Pavel Tatashin   mm: discard membl...
380
381
   */
  void __init memblock_discard(void)
5e270e254   Philipp Hachtmann   mm: free memblock...
382
  {
3010f8765   Pavel Tatashin   mm: discard membl...
383
  	phys_addr_t addr, size;
5e270e254   Philipp Hachtmann   mm: free memblock...
384

3010f8765   Pavel Tatashin   mm: discard membl...
385
386
387
388
389
390
  	if (memblock.reserved.regions != memblock_reserved_init_regions) {
  		addr = __pa(memblock.reserved.regions);
  		size = PAGE_ALIGN(sizeof(struct memblock_region) *
  				  memblock.reserved.max);
  		__memblock_free_late(addr, size);
  	}
5e270e254   Philipp Hachtmann   mm: free memblock...
391

91b540f98   Pavel Tatashin   mm/memblock.c: re...
392
  	if (memblock.memory.regions != memblock_memory_init_regions) {
3010f8765   Pavel Tatashin   mm: discard membl...
393
394
395
396
397
  		addr = __pa(memblock.memory.regions);
  		size = PAGE_ALIGN(sizeof(struct memblock_region) *
  				  memblock.memory.max);
  		__memblock_free_late(addr, size);
  	}
9f3d5eaa3   Mike Rapoport   memblock: impleme...
398
399
  
  	memblock_memory = NULL;
5e270e254   Philipp Hachtmann   mm: free memblock...
400
  }
5e270e254   Philipp Hachtmann   mm: free memblock...
401
  #endif
48c3b583b   Greg Pearson   mm/memblock: fix ...
402
403
404
405
406
407
408
409
  /**
   * memblock_double_array - double the size of the memblock regions array
   * @type: memblock type of the regions array being doubled
   * @new_area_start: starting address of memory range to avoid overlap with
   * @new_area_size: size of memory range to avoid overlap with
   *
   * Double the size of the @type regions array. If memblock is being used to
   * allocate memory for a new reserved regions array and there is a previously
47cec4432   Mike Rapoport   docs/mm: memblock...
410
   * allocated memory range [@new_area_start, @new_area_start + @new_area_size]
48c3b583b   Greg Pearson   mm/memblock: fix ...
411
412
413
   * waiting to be reserved, ensure the memory used by the new array does
   * not overlap.
   *
47cec4432   Mike Rapoport   docs/mm: memblock...
414
   * Return:
48c3b583b   Greg Pearson   mm/memblock: fix ...
415
416
417
418
419
   * 0 on success, -1 on failure.
   */
  static int __init_memblock memblock_double_array(struct memblock_type *type,
  						phys_addr_t new_area_start,
  						phys_addr_t new_area_size)
142b45a72   Benjamin Herrenschmidt   memblock: Add arr...
420
421
  {
  	struct memblock_region *new_array, *old_array;
29f673860   Yinghai Lu   memblock: free al...
422
  	phys_addr_t old_alloc_size, new_alloc_size;
a36aab890   Mike Rapoport   mm/memblock.c: re...
423
  	phys_addr_t old_size, new_size, addr, new_end;
142b45a72   Benjamin Herrenschmidt   memblock: Add arr...
424
  	int use_slab = slab_is_available();
181eb3942   Gavin Shan   mm/memblock: fix ...
425
  	int *in_slab;
142b45a72   Benjamin Herrenschmidt   memblock: Add arr...
426
427
428
429
430
431
  
  	/* We don't allow resizing until we know about the reserved regions
  	 * of memory that aren't suitable for allocation
  	 */
  	if (!memblock_can_resize)
  		return -1;
142b45a72   Benjamin Herrenschmidt   memblock: Add arr...
432
433
434
  	/* Calculate new doubled size */
  	old_size = type->max * sizeof(struct memblock_region);
  	new_size = old_size << 1;
29f673860   Yinghai Lu   memblock: free al...
435
436
437
438
439
440
  	/*
  	 * We need to allocated new one align to PAGE_SIZE,
  	 *   so we can free them completely later.
  	 */
  	old_alloc_size = PAGE_ALIGN(old_size);
  	new_alloc_size = PAGE_ALIGN(new_size);
142b45a72   Benjamin Herrenschmidt   memblock: Add arr...
441

181eb3942   Gavin Shan   mm/memblock: fix ...
442
443
444
445
446
  	/* Retrieve the slab flag */
  	if (type == &memblock.memory)
  		in_slab = &memblock_memory_in_slab;
  	else
  		in_slab = &memblock_reserved_in_slab;
a2974133b   Mike Rapoport   mm: memblock: upd...
447
  	/* Try to find some space for it */
142b45a72   Benjamin Herrenschmidt   memblock: Add arr...
448
449
  	if (use_slab) {
  		new_array = kmalloc(new_size, GFP_KERNEL);
1f5026a7e   Tejun Heo   memblock: Kill ME...
450
  		addr = new_array ? __pa(new_array) : 0;
4e2f07750   Gavin Shan   mm/memblock: clea...
451
  	} else {
48c3b583b   Greg Pearson   mm/memblock: fix ...
452
453
454
455
456
457
  		/* only exclude range when trying to double reserved.regions */
  		if (type != &memblock.reserved)
  			new_area_start = new_area_size = 0;
  
  		addr = memblock_find_in_range(new_area_start + new_area_size,
  						memblock.current_limit,
29f673860   Yinghai Lu   memblock: free al...
458
  						new_alloc_size, PAGE_SIZE);
48c3b583b   Greg Pearson   mm/memblock: fix ...
459
460
  		if (!addr && new_area_size)
  			addr = memblock_find_in_range(0,
fd07383b6   Andrew Morton   mm/memblock.c:mem...
461
462
  				min(new_area_start, memblock.current_limit),
  				new_alloc_size, PAGE_SIZE);
48c3b583b   Greg Pearson   mm/memblock: fix ...
463

15674868d   Sachin Kamat   mm/memblock: Use ...
464
  		new_array = addr ? __va(addr) : NULL;
4e2f07750   Gavin Shan   mm/memblock: clea...
465
  	}
1f5026a7e   Tejun Heo   memblock: Kill ME...
466
  	if (!addr) {
142b45a72   Benjamin Herrenschmidt   memblock: Add arr...
467
468
  		pr_err("memblock: Failed to double %s array from %ld to %ld entries !
  ",
0262d9c84   Heiko Carstens   memblock: embed m...
469
  		       type->name, type->max, type->max * 2);
142b45a72   Benjamin Herrenschmidt   memblock: Add arr...
470
471
  		return -1;
  	}
142b45a72   Benjamin Herrenschmidt   memblock: Add arr...
472

a36aab890   Mike Rapoport   mm/memblock.c: re...
473
474
475
  	new_end = addr + new_size - 1;
  	memblock_dbg("memblock: %s is doubled to %ld at [%pa-%pa]",
  			type->name, type->max * 2, &addr, &new_end);
ea9e4376b   Yinghai Lu   memblock: Improve...
476

fd07383b6   Andrew Morton   mm/memblock.c:mem...
477
478
479
480
  	/*
  	 * Found space, we now need to move the array over before we add the
  	 * reserved region since it may be our reserved array itself that is
  	 * full.
142b45a72   Benjamin Herrenschmidt   memblock: Add arr...
481
482
483
484
485
486
  	 */
  	memcpy(new_array, type->regions, old_size);
  	memset(new_array + type->max, 0, old_size);
  	old_array = type->regions;
  	type->regions = new_array;
  	type->max <<= 1;
fd07383b6   Andrew Morton   mm/memblock.c:mem...
487
  	/* Free old array. We needn't free it if the array is the static one */
181eb3942   Gavin Shan   mm/memblock: fix ...
488
489
490
491
  	if (*in_slab)
  		kfree(old_array);
  	else if (old_array != memblock_memory_init_regions &&
  		 old_array != memblock_reserved_init_regions)
29f673860   Yinghai Lu   memblock: free al...
492
  		memblock_free(__pa(old_array), old_alloc_size);
142b45a72   Benjamin Herrenschmidt   memblock: Add arr...
493

fd07383b6   Andrew Morton   mm/memblock.c:mem...
494
495
496
  	/*
  	 * Reserve the new array if that comes from the memblock.  Otherwise, we
  	 * needn't do it
181eb3942   Gavin Shan   mm/memblock: fix ...
497
498
  	 */
  	if (!use_slab)
29f673860   Yinghai Lu   memblock: free al...
499
  		BUG_ON(memblock_reserve(addr, new_alloc_size));
181eb3942   Gavin Shan   mm/memblock: fix ...
500
501
502
  
  	/* Update slab flag */
  	*in_slab = use_slab;
142b45a72   Benjamin Herrenschmidt   memblock: Add arr...
503
504
  	return 0;
  }
784656f9c   Tejun Heo   memblock: Reimple...
505
506
507
508
509
510
511
  /**
   * memblock_merge_regions - merge neighboring compatible regions
   * @type: memblock type to scan
   *
   * Scan @type and merge neighboring compatible regions.
   */
  static void __init_memblock memblock_merge_regions(struct memblock_type *type)
95f72d1ed   Yinghai Lu   lmb: rename to me...
512
  {
784656f9c   Tejun Heo   memblock: Reimple...
513
  	int i = 0;
95f72d1ed   Yinghai Lu   lmb: rename to me...
514

784656f9c   Tejun Heo   memblock: Reimple...
515
516
517
518
  	/* cnt never goes below 1 */
  	while (i < type->cnt - 1) {
  		struct memblock_region *this = &type->regions[i];
  		struct memblock_region *next = &type->regions[i + 1];
95f72d1ed   Yinghai Lu   lmb: rename to me...
519

7c0caeb86   Tejun Heo   memblock: Add opt...
520
521
  		if (this->base + this->size != next->base ||
  		    memblock_get_region_node(this) !=
66a207572   Tang Chen   memblock, numa: i...
522
523
  		    memblock_get_region_node(next) ||
  		    this->flags != next->flags) {
784656f9c   Tejun Heo   memblock: Reimple...
524
525
526
  			BUG_ON(this->base + this->size > next->base);
  			i++;
  			continue;
8f7a66051   Benjamin Herrenschmidt   mm/memblock: prop...
527
  		}
784656f9c   Tejun Heo   memblock: Reimple...
528
  		this->size += next->size;
c0232ae86   Lin Feng   mm: memblock: fix...
529
530
  		/* move forward from next + 1, index of which is i + 2 */
  		memmove(next, next + 1, (type->cnt - (i + 2)) * sizeof(*next));
784656f9c   Tejun Heo   memblock: Reimple...
531
  		type->cnt--;
95f72d1ed   Yinghai Lu   lmb: rename to me...
532
  	}
784656f9c   Tejun Heo   memblock: Reimple...
533
  }
95f72d1ed   Yinghai Lu   lmb: rename to me...
534

784656f9c   Tejun Heo   memblock: Reimple...
535
536
  /**
   * memblock_insert_region - insert new memblock region
209ff86d6   Tang Chen   memblock: fix mis...
537
538
539
540
541
   * @type:	memblock type to insert into
   * @idx:	index for the insertion point
   * @base:	base address of the new region
   * @size:	size of the new region
   * @nid:	node id of the new region
66a207572   Tang Chen   memblock, numa: i...
542
   * @flags:	flags of the new region
784656f9c   Tejun Heo   memblock: Reimple...
543
   *
47cec4432   Mike Rapoport   docs/mm: memblock...
544
   * Insert new memblock region [@base, @base + @size) into @type at @idx.
412d0008d   Alexander Kuleshov   mm/memblock: fix ...
545
   * @type must already have extra room to accommodate the new region.
784656f9c   Tejun Heo   memblock: Reimple...
546
547
548
   */
  static void __init_memblock memblock_insert_region(struct memblock_type *type,
  						   int idx, phys_addr_t base,
66a207572   Tang Chen   memblock, numa: i...
549
  						   phys_addr_t size,
e1720fee2   Mike Rapoport   mm/memblock: add ...
550
551
  						   int nid,
  						   enum memblock_flags flags)
784656f9c   Tejun Heo   memblock: Reimple...
552
553
554
555
556
557
558
  {
  	struct memblock_region *rgn = &type->regions[idx];
  
  	BUG_ON(type->cnt >= type->max);
  	memmove(rgn + 1, rgn, (type->cnt - idx) * sizeof(*rgn));
  	rgn->base = base;
  	rgn->size = size;
66a207572   Tang Chen   memblock, numa: i...
559
  	rgn->flags = flags;
7c0caeb86   Tejun Heo   memblock: Add opt...
560
  	memblock_set_region_node(rgn, nid);
784656f9c   Tejun Heo   memblock: Reimple...
561
  	type->cnt++;
1440c4e2c   Tejun Heo   memblock: Track t...
562
  	type->total_size += size;
784656f9c   Tejun Heo   memblock: Reimple...
563
564
565
  }
  
  /**
f1af9d3af   Philipp Hachtmann   mm/memblock: Do s...
566
   * memblock_add_range - add new memblock region
784656f9c   Tejun Heo   memblock: Reimple...
567
568
569
   * @type: memblock type to add new region into
   * @base: base address of the new region
   * @size: size of the new region
7fb0bc3f0   Tejun Heo   memblock: Impleme...
570
   * @nid: nid of the new region
66a207572   Tang Chen   memblock, numa: i...
571
   * @flags: flags of the new region
784656f9c   Tejun Heo   memblock: Reimple...
572
   *
47cec4432   Mike Rapoport   docs/mm: memblock...
573
   * Add new memblock region [@base, @base + @size) into @type.  The new region
784656f9c   Tejun Heo   memblock: Reimple...
574
575
576
577
   * is allowed to overlap with existing ones - overlaps don't affect already
   * existing regions.  @type is guaranteed to be minimal (all neighbouring
   * compatible regions are merged) after the addition.
   *
47cec4432   Mike Rapoport   docs/mm: memblock...
578
   * Return:
784656f9c   Tejun Heo   memblock: Reimple...
579
580
   * 0 on success, -errno on failure.
   */
02634a44b   Anshuman Khandual   mm/memblock: defi...
581
  static int __init_memblock memblock_add_range(struct memblock_type *type,
66a207572   Tang Chen   memblock, numa: i...
582
  				phys_addr_t base, phys_addr_t size,
e1720fee2   Mike Rapoport   mm/memblock: add ...
583
  				int nid, enum memblock_flags flags)
784656f9c   Tejun Heo   memblock: Reimple...
584
585
  {
  	bool insert = false;
eb18f1b5b   Tejun Heo   memblock: Make me...
586
587
  	phys_addr_t obase = base;
  	phys_addr_t end = base + memblock_cap_size(base, &size);
8c9c1701c   Alexander Kuleshov   mm/memblock: intr...
588
589
  	int idx, nr_new;
  	struct memblock_region *rgn;
784656f9c   Tejun Heo   memblock: Reimple...
590

b3dc627ca   Tejun Heo   memblock: membloc...
591
592
  	if (!size)
  		return 0;
784656f9c   Tejun Heo   memblock: Reimple...
593
594
  	/* special case for empty array */
  	if (type->regions[0].size == 0) {
1440c4e2c   Tejun Heo   memblock: Track t...
595
  		WARN_ON(type->cnt != 1 || type->total_size);
8f7a66051   Benjamin Herrenschmidt   mm/memblock: prop...
596
597
  		type->regions[0].base = base;
  		type->regions[0].size = size;
66a207572   Tang Chen   memblock, numa: i...
598
  		type->regions[0].flags = flags;
7fb0bc3f0   Tejun Heo   memblock: Impleme...
599
  		memblock_set_region_node(&type->regions[0], nid);
1440c4e2c   Tejun Heo   memblock: Track t...
600
  		type->total_size = size;
8f7a66051   Benjamin Herrenschmidt   mm/memblock: prop...
601
  		return 0;
95f72d1ed   Yinghai Lu   lmb: rename to me...
602
  	}
784656f9c   Tejun Heo   memblock: Reimple...
603
604
605
606
  repeat:
  	/*
  	 * The following is executed twice.  Once with %false @insert and
  	 * then with %true.  The first counts the number of regions needed
412d0008d   Alexander Kuleshov   mm/memblock: fix ...
607
  	 * to accommodate the new area.  The second actually inserts them.
142b45a72   Benjamin Herrenschmidt   memblock: Add arr...
608
  	 */
784656f9c   Tejun Heo   memblock: Reimple...
609
610
  	base = obase;
  	nr_new = 0;
95f72d1ed   Yinghai Lu   lmb: rename to me...
611

66e8b438b   Gioh Kim   mm/memblock.c: ma...
612
  	for_each_memblock_type(idx, type, rgn) {
784656f9c   Tejun Heo   memblock: Reimple...
613
614
615
616
  		phys_addr_t rbase = rgn->base;
  		phys_addr_t rend = rbase + rgn->size;
  
  		if (rbase >= end)
95f72d1ed   Yinghai Lu   lmb: rename to me...
617
  			break;
784656f9c   Tejun Heo   memblock: Reimple...
618
619
620
621
622
623
624
  		if (rend <= base)
  			continue;
  		/*
  		 * @rgn overlaps.  If it separates the lower part of new
  		 * area, insert that portion.
  		 */
  		if (rbase > base) {
3f08a302f   Mike Rapoport   mm: remove CONFIG...
625
  #ifdef CONFIG_NEED_MULTIPLE_NODES
c0a294988   Wei Yang   mm/memblock: WARN...
626
627
  			WARN_ON(nid != memblock_get_region_node(rgn));
  #endif
4fcab5f43   Wei Yang   mm/memblock.c: WA...
628
  			WARN_ON(flags != rgn->flags);
784656f9c   Tejun Heo   memblock: Reimple...
629
630
  			nr_new++;
  			if (insert)
8c9c1701c   Alexander Kuleshov   mm/memblock: intr...
631
  				memblock_insert_region(type, idx++, base,
66a207572   Tang Chen   memblock, numa: i...
632
633
  						       rbase - base, nid,
  						       flags);
95f72d1ed   Yinghai Lu   lmb: rename to me...
634
  		}
784656f9c   Tejun Heo   memblock: Reimple...
635
636
  		/* area below @rend is dealt with, forget about it */
  		base = min(rend, end);
95f72d1ed   Yinghai Lu   lmb: rename to me...
637
  	}
784656f9c   Tejun Heo   memblock: Reimple...
638
639
640
641
642
  
  	/* insert the remaining portion */
  	if (base < end) {
  		nr_new++;
  		if (insert)
8c9c1701c   Alexander Kuleshov   mm/memblock: intr...
643
  			memblock_insert_region(type, idx, base, end - base,
66a207572   Tang Chen   memblock, numa: i...
644
  					       nid, flags);
95f72d1ed   Yinghai Lu   lmb: rename to me...
645
  	}
95f72d1ed   Yinghai Lu   lmb: rename to me...
646

ef3cc4db4   nimisolo   mm/memblock.c:mem...
647
648
  	if (!nr_new)
  		return 0;
784656f9c   Tejun Heo   memblock: Reimple...
649
650
651
  	/*
  	 * If this was the first round, resize array and repeat for actual
  	 * insertions; otherwise, merge and return.
142b45a72   Benjamin Herrenschmidt   memblock: Add arr...
652
  	 */
784656f9c   Tejun Heo   memblock: Reimple...
653
654
  	if (!insert) {
  		while (type->cnt + nr_new > type->max)
48c3b583b   Greg Pearson   mm/memblock: fix ...
655
  			if (memblock_double_array(type, obase, size) < 0)
784656f9c   Tejun Heo   memblock: Reimple...
656
657
658
659
660
661
  				return -ENOMEM;
  		insert = true;
  		goto repeat;
  	} else {
  		memblock_merge_regions(type);
  		return 0;
142b45a72   Benjamin Herrenschmidt   memblock: Add arr...
662
  	}
95f72d1ed   Yinghai Lu   lmb: rename to me...
663
  }
48a833cc7   Mike Rapoport   docs/mm: memblock...
664
665
666
667
668
669
670
671
672
673
674
675
  /**
   * memblock_add_node - add new memblock region within a NUMA node
   * @base: base address of the new region
   * @size: size of the new region
   * @nid: nid of the new region
   *
   * Add new memblock region [@base, @base + @size) to the "memory"
   * type. See memblock_add_range() description for mode details
   *
   * Return:
   * 0 on success, -errno on failure.
   */
7fb0bc3f0   Tejun Heo   memblock: Impleme...
676
677
678
  int __init_memblock memblock_add_node(phys_addr_t base, phys_addr_t size,
  				       int nid)
  {
f1af9d3af   Philipp Hachtmann   mm/memblock: Do s...
679
  	return memblock_add_range(&memblock.memory, base, size, nid, 0);
7fb0bc3f0   Tejun Heo   memblock: Impleme...
680
  }
48a833cc7   Mike Rapoport   docs/mm: memblock...
681
682
683
684
685
686
687
688
689
690
691
  /**
   * memblock_add - add new memblock region
   * @base: base address of the new region
   * @size: size of the new region
   *
   * Add new memblock region [@base, @base + @size) to the "memory"
   * type. See memblock_add_range() description for mode details
   *
   * Return:
   * 0 on success, -errno on failure.
   */
f705ac4b3   Alexander Kuleshov   mm/memblock.c: mo...
692
  int __init_memblock memblock_add(phys_addr_t base, phys_addr_t size)
6a4055bc7   Alexander Kuleshov   mm/memblock.c: ad...
693
  {
5d63f81c9   Miles Chen   mm/memblock.c: re...
694
  	phys_addr_t end = base + size - 1;
a090d711d   Anshuman Khandual   memblock: Use __f...
695
696
  	memblock_dbg("%s: [%pa-%pa] %pS
  ", __func__,
5d63f81c9   Miles Chen   mm/memblock.c: re...
697
  		     &base, &end, (void *)_RET_IP_);
6a4055bc7   Alexander Kuleshov   mm/memblock.c: ad...
698

f705ac4b3   Alexander Kuleshov   mm/memblock.c: mo...
699
  	return memblock_add_range(&memblock.memory, base, size, MAX_NUMNODES, 0);
95f72d1ed   Yinghai Lu   lmb: rename to me...
700
  }
6a9ceb31c   Tejun Heo   memblock: Separat...
701
702
703
704
705
706
707
708
709
  /**
   * memblock_isolate_range - isolate given range into disjoint memblocks
   * @type: memblock type to isolate range for
   * @base: base of range to isolate
   * @size: size of range to isolate
   * @start_rgn: out parameter for the start of isolated region
   * @end_rgn: out parameter for the end of isolated region
   *
   * Walk @type and ensure that regions don't cross the boundaries defined by
47cec4432   Mike Rapoport   docs/mm: memblock...
710
   * [@base, @base + @size).  Crossing regions are split at the boundaries,
6a9ceb31c   Tejun Heo   memblock: Separat...
711
712
713
   * which may create at most two more regions.  The index of the first
   * region inside the range is returned in *@start_rgn and end in *@end_rgn.
   *
47cec4432   Mike Rapoport   docs/mm: memblock...
714
   * Return:
6a9ceb31c   Tejun Heo   memblock: Separat...
715
716
717
718
719
720
   * 0 on success, -errno on failure.
   */
  static int __init_memblock memblock_isolate_range(struct memblock_type *type,
  					phys_addr_t base, phys_addr_t size,
  					int *start_rgn, int *end_rgn)
  {
eb18f1b5b   Tejun Heo   memblock: Make me...
721
  	phys_addr_t end = base + memblock_cap_size(base, &size);
8c9c1701c   Alexander Kuleshov   mm/memblock: intr...
722
723
  	int idx;
  	struct memblock_region *rgn;
6a9ceb31c   Tejun Heo   memblock: Separat...
724
725
  
  	*start_rgn = *end_rgn = 0;
b3dc627ca   Tejun Heo   memblock: membloc...
726
727
  	if (!size)
  		return 0;
6a9ceb31c   Tejun Heo   memblock: Separat...
728
729
  	/* we'll create at most two more regions */
  	while (type->cnt + 2 > type->max)
48c3b583b   Greg Pearson   mm/memblock: fix ...
730
  		if (memblock_double_array(type, base, size) < 0)
6a9ceb31c   Tejun Heo   memblock: Separat...
731
  			return -ENOMEM;
66e8b438b   Gioh Kim   mm/memblock.c: ma...
732
  	for_each_memblock_type(idx, type, rgn) {
6a9ceb31c   Tejun Heo   memblock: Separat...
733
734
735
736
737
738
739
740
741
742
743
744
745
746
  		phys_addr_t rbase = rgn->base;
  		phys_addr_t rend = rbase + rgn->size;
  
  		if (rbase >= end)
  			break;
  		if (rend <= base)
  			continue;
  
  		if (rbase < base) {
  			/*
  			 * @rgn intersects from below.  Split and continue
  			 * to process the next region - the new top half.
  			 */
  			rgn->base = base;
1440c4e2c   Tejun Heo   memblock: Track t...
747
748
  			rgn->size -= base - rbase;
  			type->total_size -= base - rbase;
8c9c1701c   Alexander Kuleshov   mm/memblock: intr...
749
  			memblock_insert_region(type, idx, rbase, base - rbase,
66a207572   Tang Chen   memblock, numa: i...
750
751
  					       memblock_get_region_node(rgn),
  					       rgn->flags);
6a9ceb31c   Tejun Heo   memblock: Separat...
752
753
754
755
756
757
  		} else if (rend > end) {
  			/*
  			 * @rgn intersects from above.  Split and redo the
  			 * current region - the new bottom half.
  			 */
  			rgn->base = end;
1440c4e2c   Tejun Heo   memblock: Track t...
758
759
  			rgn->size -= end - rbase;
  			type->total_size -= end - rbase;
8c9c1701c   Alexander Kuleshov   mm/memblock: intr...
760
  			memblock_insert_region(type, idx--, rbase, end - rbase,
66a207572   Tang Chen   memblock, numa: i...
761
762
  					       memblock_get_region_node(rgn),
  					       rgn->flags);
6a9ceb31c   Tejun Heo   memblock: Separat...
763
764
765
  		} else {
  			/* @rgn is fully contained, record it */
  			if (!*end_rgn)
8c9c1701c   Alexander Kuleshov   mm/memblock: intr...
766
767
  				*start_rgn = idx;
  			*end_rgn = idx + 1;
6a9ceb31c   Tejun Heo   memblock: Separat...
768
769
770
771
772
  		}
  	}
  
  	return 0;
  }
6a9ceb31c   Tejun Heo   memblock: Separat...
773

35bd16a22   Alexander Kuleshov   mm/memblock: make...
774
  static int __init_memblock memblock_remove_range(struct memblock_type *type,
f1af9d3af   Philipp Hachtmann   mm/memblock: Do s...
775
  					  phys_addr_t base, phys_addr_t size)
95f72d1ed   Yinghai Lu   lmb: rename to me...
776
  {
719361809   Tejun Heo   memblock: Reimple...
777
778
  	int start_rgn, end_rgn;
  	int i, ret;
95f72d1ed   Yinghai Lu   lmb: rename to me...
779

719361809   Tejun Heo   memblock: Reimple...
780
781
782
  	ret = memblock_isolate_range(type, base, size, &start_rgn, &end_rgn);
  	if (ret)
  		return ret;
95f72d1ed   Yinghai Lu   lmb: rename to me...
783

719361809   Tejun Heo   memblock: Reimple...
784
785
  	for (i = end_rgn - 1; i >= start_rgn; i--)
  		memblock_remove_region(type, i);
8f7a66051   Benjamin Herrenschmidt   mm/memblock: prop...
786
  	return 0;
95f72d1ed   Yinghai Lu   lmb: rename to me...
787
  }
581adcbe1   Tejun Heo   memblock: Make me...
788
  int __init_memblock memblock_remove(phys_addr_t base, phys_addr_t size)
95f72d1ed   Yinghai Lu   lmb: rename to me...
789
  {
25cf23d7a   Minchan Kim   mm/memblock: prin...
790
  	phys_addr_t end = base + size - 1;
a090d711d   Anshuman Khandual   memblock: Use __f...
791
792
  	memblock_dbg("%s: [%pa-%pa] %pS
  ", __func__,
25cf23d7a   Minchan Kim   mm/memblock: prin...
793
  		     &base, &end, (void *)_RET_IP_);
f1af9d3af   Philipp Hachtmann   mm/memblock: Do s...
794
  	return memblock_remove_range(&memblock.memory, base, size);
95f72d1ed   Yinghai Lu   lmb: rename to me...
795
  }
4d72868c8   Mike Rapoport   memblock: replace...
796
797
798
799
800
801
802
803
  /**
   * memblock_free - free boot memory block
   * @base: phys starting address of the  boot memory block
   * @size: size of the boot memory block in bytes
   *
   * Free boot memory block previously allocated by memblock_alloc_xx() API.
   * The freeing memory will not be released to the buddy allocator.
   */
581adcbe1   Tejun Heo   memblock: Make me...
804
  int __init_memblock memblock_free(phys_addr_t base, phys_addr_t size)
95f72d1ed   Yinghai Lu   lmb: rename to me...
805
  {
5d63f81c9   Miles Chen   mm/memblock.c: re...
806
  	phys_addr_t end = base + size - 1;
a090d711d   Anshuman Khandual   memblock: Use __f...
807
808
  	memblock_dbg("%s: [%pa-%pa] %pS
  ", __func__,
5d63f81c9   Miles Chen   mm/memblock.c: re...
809
  		     &base, &end, (void *)_RET_IP_);
24aa07882   Tejun Heo   memblock, x86: Re...
810

9099daed9   Catalin Marinas   mm: kmemleak: avo...
811
  	kmemleak_free_part_phys(base, size);
f1af9d3af   Philipp Hachtmann   mm/memblock: Do s...
812
  	return memblock_remove_range(&memblock.reserved, base, size);
95f72d1ed   Yinghai Lu   lmb: rename to me...
813
  }
f705ac4b3   Alexander Kuleshov   mm/memblock.c: mo...
814
  int __init_memblock memblock_reserve(phys_addr_t base, phys_addr_t size)
95f72d1ed   Yinghai Lu   lmb: rename to me...
815
  {
5d63f81c9   Miles Chen   mm/memblock.c: re...
816
  	phys_addr_t end = base + size - 1;
a090d711d   Anshuman Khandual   memblock: Use __f...
817
818
  	memblock_dbg("%s: [%pa-%pa] %pS
  ", __func__,
5d63f81c9   Miles Chen   mm/memblock.c: re...
819
  		     &base, &end, (void *)_RET_IP_);
95f72d1ed   Yinghai Lu   lmb: rename to me...
820

f705ac4b3   Alexander Kuleshov   mm/memblock.c: mo...
821
  	return memblock_add_range(&memblock.reserved, base, size, MAX_NUMNODES, 0);
95f72d1ed   Yinghai Lu   lmb: rename to me...
822
  }
02634a44b   Anshuman Khandual   mm/memblock: defi...
823
824
825
826
827
828
829
830
  #ifdef CONFIG_HAVE_MEMBLOCK_PHYS_MAP
  int __init_memblock memblock_physmem_add(phys_addr_t base, phys_addr_t size)
  {
  	phys_addr_t end = base + size - 1;
  
  	memblock_dbg("%s: [%pa-%pa] %pS
  ", __func__,
  		     &base, &end, (void *)_RET_IP_);
776499058   David Hildenbrand   mm/memblock: expo...
831
  	return memblock_add_range(&physmem, base, size, MAX_NUMNODES, 0);
02634a44b   Anshuman Khandual   mm/memblock: defi...
832
833
  }
  #endif
35fd0808d   Tejun Heo   memblock: Impleme...
834
  /**
47cec4432   Mike Rapoport   docs/mm: memblock...
835
836
837
838
839
   * memblock_setclr_flag - set or clear flag for a memory region
   * @base: base address of the region
   * @size: size of the region
   * @set: set or clear the flag
   * @flag: the flag to udpate
66b16edf9   Tang Chen   memblock, mem_hot...
840
   *
4308ce17f   Tony Luck   mm/memblock.c: re...
841
   * This function isolates region [@base, @base + @size), and sets/clears flag
66b16edf9   Tang Chen   memblock, mem_hot...
842
   *
47cec4432   Mike Rapoport   docs/mm: memblock...
843
   * Return: 0 on success, -errno on failure.
66b16edf9   Tang Chen   memblock, mem_hot...
844
   */
4308ce17f   Tony Luck   mm/memblock.c: re...
845
846
  static int __init_memblock memblock_setclr_flag(phys_addr_t base,
  				phys_addr_t size, int set, int flag)
66b16edf9   Tang Chen   memblock, mem_hot...
847
848
849
850
851
852
853
  {
  	struct memblock_type *type = &memblock.memory;
  	int i, ret, start_rgn, end_rgn;
  
  	ret = memblock_isolate_range(type, base, size, &start_rgn, &end_rgn);
  	if (ret)
  		return ret;
fe145124d   Mike Rapoport   memblock: remove ...
854
855
  	for (i = start_rgn; i < end_rgn; i++) {
  		struct memblock_region *r = &type->regions[i];
4308ce17f   Tony Luck   mm/memblock.c: re...
856
  		if (set)
fe145124d   Mike Rapoport   memblock: remove ...
857
  			r->flags |= flag;
4308ce17f   Tony Luck   mm/memblock.c: re...
858
  		else
fe145124d   Mike Rapoport   memblock: remove ...
859
860
  			r->flags &= ~flag;
  	}
66b16edf9   Tang Chen   memblock, mem_hot...
861
862
863
864
865
866
  
  	memblock_merge_regions(type);
  	return 0;
  }
  
  /**
4308ce17f   Tony Luck   mm/memblock.c: re...
867
   * memblock_mark_hotplug - Mark hotpluggable memory with flag MEMBLOCK_HOTPLUG.
66b16edf9   Tang Chen   memblock, mem_hot...
868
869
870
   * @base: the base phys addr of the region
   * @size: the size of the region
   *
47cec4432   Mike Rapoport   docs/mm: memblock...
871
   * Return: 0 on success, -errno on failure.
4308ce17f   Tony Luck   mm/memblock.c: re...
872
873
874
875
876
877
878
879
880
881
   */
  int __init_memblock memblock_mark_hotplug(phys_addr_t base, phys_addr_t size)
  {
  	return memblock_setclr_flag(base, size, 1, MEMBLOCK_HOTPLUG);
  }
  
  /**
   * memblock_clear_hotplug - Clear flag MEMBLOCK_HOTPLUG for a specified region.
   * @base: the base phys addr of the region
   * @size: the size of the region
66b16edf9   Tang Chen   memblock, mem_hot...
882
   *
47cec4432   Mike Rapoport   docs/mm: memblock...
883
   * Return: 0 on success, -errno on failure.
66b16edf9   Tang Chen   memblock, mem_hot...
884
885
886
   */
  int __init_memblock memblock_clear_hotplug(phys_addr_t base, phys_addr_t size)
  {
4308ce17f   Tony Luck   mm/memblock.c: re...
887
  	return memblock_setclr_flag(base, size, 0, MEMBLOCK_HOTPLUG);
66b16edf9   Tang Chen   memblock, mem_hot...
888
889
890
  }
  
  /**
a3f5bafcc   Tony Luck   mm/memblock: allo...
891
892
893
894
   * memblock_mark_mirror - Mark mirrored memory with flag MEMBLOCK_MIRROR.
   * @base: the base phys addr of the region
   * @size: the size of the region
   *
47cec4432   Mike Rapoport   docs/mm: memblock...
895
   * Return: 0 on success, -errno on failure.
a3f5bafcc   Tony Luck   mm/memblock: allo...
896
897
898
899
900
901
902
   */
  int __init_memblock memblock_mark_mirror(phys_addr_t base, phys_addr_t size)
  {
  	system_has_some_mirror = true;
  
  	return memblock_setclr_flag(base, size, 1, MEMBLOCK_MIRROR);
  }
bf3d3cc58   Ard Biesheuvel   mm/memblock: add ...
903
904
905
906
907
  /**
   * memblock_mark_nomap - Mark a memory region with flag MEMBLOCK_NOMAP.
   * @base: the base phys addr of the region
   * @size: the size of the region
   *
47cec4432   Mike Rapoport   docs/mm: memblock...
908
   * Return: 0 on success, -errno on failure.
bf3d3cc58   Ard Biesheuvel   mm/memblock: add ...
909
910
911
912
913
   */
  int __init_memblock memblock_mark_nomap(phys_addr_t base, phys_addr_t size)
  {
  	return memblock_setclr_flag(base, size, 1, MEMBLOCK_NOMAP);
  }
a3f5bafcc   Tony Luck   mm/memblock: allo...
914
915
  
  /**
4c546b8a3   AKASHI Takahiro   memblock: add mem...
916
917
918
919
   * memblock_clear_nomap - Clear flag MEMBLOCK_NOMAP for a specified region.
   * @base: the base phys addr of the region
   * @size: the size of the region
   *
47cec4432   Mike Rapoport   docs/mm: memblock...
920
   * Return: 0 on success, -errno on failure.
4c546b8a3   AKASHI Takahiro   memblock: add mem...
921
922
923
924
925
   */
  int __init_memblock memblock_clear_nomap(phys_addr_t base, phys_addr_t size)
  {
  	return memblock_setclr_flag(base, size, 0, MEMBLOCK_NOMAP);
  }
9f3d5eaa3   Mike Rapoport   memblock: impleme...
926
927
928
  static bool should_skip_region(struct memblock_type *type,
  			       struct memblock_region *m,
  			       int nid, int flags)
c9a688a3e   Mike Rapoport   memblock: split c...
929
930
  {
  	int m_nid = memblock_get_region_node(m);
9f3d5eaa3   Mike Rapoport   memblock: impleme...
931
932
933
  	/* we never skip regions when iterating memblock.reserved or physmem */
  	if (type != memblock_memory)
  		return false;
c9a688a3e   Mike Rapoport   memblock: split c...
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
  	/* only memory regions are associated with nodes, check it */
  	if (nid != NUMA_NO_NODE && nid != m_nid)
  		return true;
  
  	/* skip hotpluggable memory regions if needed */
  	if (movable_node_is_enabled() && memblock_is_hotpluggable(m))
  		return true;
  
  	/* if we want mirror memory skip non-mirror memory regions */
  	if ((flags & MEMBLOCK_MIRROR) && !memblock_is_mirror(m))
  		return true;
  
  	/* skip nomap memory unless we were asked for it explicitly */
  	if (!(flags & MEMBLOCK_NOMAP) && memblock_is_nomap(m))
  		return true;
  
  	return false;
  }
8e7a7f861   Robin Holt   memblock: introdu...
952
  /**
a2974133b   Mike Rapoport   mm: memblock: upd...
953
   * __next_mem_range - next function for for_each_free_mem_range() etc.
35fd0808d   Tejun Heo   memblock: Impleme...
954
   * @idx: pointer to u64 loop variable
b11542335   Grygorii Strashko   mm/memblock: swit...
955
   * @nid: node selector, %NUMA_NO_NODE for all nodes
fc6daaf93   Tony Luck   mm/memblock: add ...
956
   * @flags: pick from blocks based on memory attributes
f1af9d3af   Philipp Hachtmann   mm/memblock: Do s...
957
958
   * @type_a: pointer to memblock_type from where the range is taken
   * @type_b: pointer to memblock_type which excludes memory from being taken
dad7557eb   Wanpeng Li   mm: fix kernel-do...
959
960
961
   * @out_start: ptr to phys_addr_t for start address of the range, can be %NULL
   * @out_end: ptr to phys_addr_t for end address of the range, can be %NULL
   * @out_nid: ptr to int for nid of the range, can be %NULL
35fd0808d   Tejun Heo   memblock: Impleme...
962
   *
f1af9d3af   Philipp Hachtmann   mm/memblock: Do s...
963
   * Find the first area from *@idx which matches @nid, fill the out
35fd0808d   Tejun Heo   memblock: Impleme...
964
   * parameters, and update *@idx for the next iteration.  The lower 32bit of
f1af9d3af   Philipp Hachtmann   mm/memblock: Do s...
965
966
   * *@idx contains index into type_a and the upper 32bit indexes the
   * areas before each region in type_b.	For example, if type_b regions
35fd0808d   Tejun Heo   memblock: Impleme...
967
968
969
970
971
972
973
974
975
976
977
   * look like the following,
   *
   *	0:[0-16), 1:[32-48), 2:[128-130)
   *
   * The upper 32bit indexes the following regions.
   *
   *	0:[0-0), 1:[16-32), 2:[48-128), 3:[130-MAX)
   *
   * As both region arrays are sorted, the function advances the two indices
   * in lockstep and returns each intersection.
   */
776499058   David Hildenbrand   mm/memblock: expo...
978
979
980
981
  void __next_mem_range(u64 *idx, int nid, enum memblock_flags flags,
  		      struct memblock_type *type_a,
  		      struct memblock_type *type_b, phys_addr_t *out_start,
  		      phys_addr_t *out_end, int *out_nid)
35fd0808d   Tejun Heo   memblock: Impleme...
982
  {
f1af9d3af   Philipp Hachtmann   mm/memblock: Do s...
983
984
  	int idx_a = *idx & 0xffffffff;
  	int idx_b = *idx >> 32;
b11542335   Grygorii Strashko   mm/memblock: swit...
985

f1af9d3af   Philipp Hachtmann   mm/memblock: Do s...
986
987
988
  	if (WARN_ONCE(nid == MAX_NUMNODES,
  	"Usage of MAX_NUMNODES is deprecated. Use NUMA_NO_NODE instead
  "))
560dca27a   Grygorii Strashko   mm/memblock: use ...
989
  		nid = NUMA_NO_NODE;
35fd0808d   Tejun Heo   memblock: Impleme...
990

f1af9d3af   Philipp Hachtmann   mm/memblock: Do s...
991
992
  	for (; idx_a < type_a->cnt; idx_a++) {
  		struct memblock_region *m = &type_a->regions[idx_a];
35fd0808d   Tejun Heo   memblock: Impleme...
993
994
  		phys_addr_t m_start = m->base;
  		phys_addr_t m_end = m->base + m->size;
f1af9d3af   Philipp Hachtmann   mm/memblock: Do s...
995
  		int	    m_nid = memblock_get_region_node(m);
35fd0808d   Tejun Heo   memblock: Impleme...
996

9f3d5eaa3   Mike Rapoport   memblock: impleme...
997
  		if (should_skip_region(type_a, m, nid, flags))
bf3d3cc58   Ard Biesheuvel   mm/memblock: add ...
998
  			continue;
f1af9d3af   Philipp Hachtmann   mm/memblock: Do s...
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
  		if (!type_b) {
  			if (out_start)
  				*out_start = m_start;
  			if (out_end)
  				*out_end = m_end;
  			if (out_nid)
  				*out_nid = m_nid;
  			idx_a++;
  			*idx = (u32)idx_a | (u64)idx_b << 32;
  			return;
  		}
  
  		/* scan areas before each reservation */
  		for (; idx_b < type_b->cnt + 1; idx_b++) {
  			struct memblock_region *r;
  			phys_addr_t r_start;
  			phys_addr_t r_end;
  
  			r = &type_b->regions[idx_b];
  			r_start = idx_b ? r[-1].base + r[-1].size : 0;
  			r_end = idx_b < type_b->cnt ?
1c4bc43dd   Stefan Agner   mm/memblock: intr...
1020
  				r->base : PHYS_ADDR_MAX;
35fd0808d   Tejun Heo   memblock: Impleme...
1021

f1af9d3af   Philipp Hachtmann   mm/memblock: Do s...
1022
1023
1024
1025
  			/*
  			 * if idx_b advanced past idx_a,
  			 * break out to advance idx_a
  			 */
35fd0808d   Tejun Heo   memblock: Impleme...
1026
1027
1028
1029
1030
  			if (r_start >= m_end)
  				break;
  			/* if the two regions intersect, we're done */
  			if (m_start < r_end) {
  				if (out_start)
f1af9d3af   Philipp Hachtmann   mm/memblock: Do s...
1031
1032
  					*out_start =
  						max(m_start, r_start);
35fd0808d   Tejun Heo   memblock: Impleme...
1033
1034
1035
  				if (out_end)
  					*out_end = min(m_end, r_end);
  				if (out_nid)
f1af9d3af   Philipp Hachtmann   mm/memblock: Do s...
1036
  					*out_nid = m_nid;
35fd0808d   Tejun Heo   memblock: Impleme...
1037
  				/*
f1af9d3af   Philipp Hachtmann   mm/memblock: Do s...
1038
1039
  				 * The region which ends first is
  				 * advanced for the next iteration.
35fd0808d   Tejun Heo   memblock: Impleme...
1040
1041
  				 */
  				if (m_end <= r_end)
f1af9d3af   Philipp Hachtmann   mm/memblock: Do s...
1042
  					idx_a++;
35fd0808d   Tejun Heo   memblock: Impleme...
1043
  				else
f1af9d3af   Philipp Hachtmann   mm/memblock: Do s...
1044
1045
  					idx_b++;
  				*idx = (u32)idx_a | (u64)idx_b << 32;
35fd0808d   Tejun Heo   memblock: Impleme...
1046
1047
1048
1049
1050
1051
1052
1053
  				return;
  			}
  		}
  	}
  
  	/* signal end of iteration */
  	*idx = ULLONG_MAX;
  }
7bd0b0f0d   Tejun Heo   memblock: Reimple...
1054
  /**
f1af9d3af   Philipp Hachtmann   mm/memblock: Do s...
1055
1056
   * __next_mem_range_rev - generic next function for for_each_*_range_rev()
   *
7bd0b0f0d   Tejun Heo   memblock: Reimple...
1057
   * @idx: pointer to u64 loop variable
ad5ea8cd5   Alexander Kuleshov   mm/memblock.c: fi...
1058
   * @nid: node selector, %NUMA_NO_NODE for all nodes
fc6daaf93   Tony Luck   mm/memblock: add ...
1059
   * @flags: pick from blocks based on memory attributes
f1af9d3af   Philipp Hachtmann   mm/memblock: Do s...
1060
1061
   * @type_a: pointer to memblock_type from where the range is taken
   * @type_b: pointer to memblock_type which excludes memory from being taken
dad7557eb   Wanpeng Li   mm: fix kernel-do...
1062
1063
1064
   * @out_start: ptr to phys_addr_t for start address of the range, can be %NULL
   * @out_end: ptr to phys_addr_t for end address of the range, can be %NULL
   * @out_nid: ptr to int for nid of the range, can be %NULL
7bd0b0f0d   Tejun Heo   memblock: Reimple...
1065
   *
47cec4432   Mike Rapoport   docs/mm: memblock...
1066
1067
1068
   * Finds the next range from type_a which is not marked as unsuitable
   * in type_b.
   *
f1af9d3af   Philipp Hachtmann   mm/memblock: Do s...
1069
   * Reverse of __next_mem_range().
7bd0b0f0d   Tejun Heo   memblock: Reimple...
1070
   */
e1720fee2   Mike Rapoport   mm/memblock: add ...
1071
1072
  void __init_memblock __next_mem_range_rev(u64 *idx, int nid,
  					  enum memblock_flags flags,
f1af9d3af   Philipp Hachtmann   mm/memblock: Do s...
1073
1074
1075
1076
  					  struct memblock_type *type_a,
  					  struct memblock_type *type_b,
  					  phys_addr_t *out_start,
  					  phys_addr_t *out_end, int *out_nid)
7bd0b0f0d   Tejun Heo   memblock: Reimple...
1077
  {
f1af9d3af   Philipp Hachtmann   mm/memblock: Do s...
1078
1079
  	int idx_a = *idx & 0xffffffff;
  	int idx_b = *idx >> 32;
b11542335   Grygorii Strashko   mm/memblock: swit...
1080

560dca27a   Grygorii Strashko   mm/memblock: use ...
1081
1082
1083
  	if (WARN_ONCE(nid == MAX_NUMNODES, "Usage of MAX_NUMNODES is deprecated. Use NUMA_NO_NODE instead
  "))
  		nid = NUMA_NO_NODE;
7bd0b0f0d   Tejun Heo   memblock: Reimple...
1084
1085
  
  	if (*idx == (u64)ULLONG_MAX) {
f1af9d3af   Philipp Hachtmann   mm/memblock: Do s...
1086
  		idx_a = type_a->cnt - 1;
e47608ab6   zijun_hu   mm/memblock.c: fi...
1087
1088
1089
1090
  		if (type_b != NULL)
  			idx_b = type_b->cnt;
  		else
  			idx_b = 0;
7bd0b0f0d   Tejun Heo   memblock: Reimple...
1091
  	}
f1af9d3af   Philipp Hachtmann   mm/memblock: Do s...
1092
1093
  	for (; idx_a >= 0; idx_a--) {
  		struct memblock_region *m = &type_a->regions[idx_a];
7bd0b0f0d   Tejun Heo   memblock: Reimple...
1094
1095
  		phys_addr_t m_start = m->base;
  		phys_addr_t m_end = m->base + m->size;
f1af9d3af   Philipp Hachtmann   mm/memblock: Do s...
1096
  		int m_nid = memblock_get_region_node(m);
7bd0b0f0d   Tejun Heo   memblock: Reimple...
1097

9f3d5eaa3   Mike Rapoport   memblock: impleme...
1098
  		if (should_skip_region(type_a, m, nid, flags))
bf3d3cc58   Ard Biesheuvel   mm/memblock: add ...
1099
  			continue;
f1af9d3af   Philipp Hachtmann   mm/memblock: Do s...
1100
1101
1102
1103
1104
1105
1106
  		if (!type_b) {
  			if (out_start)
  				*out_start = m_start;
  			if (out_end)
  				*out_end = m_end;
  			if (out_nid)
  				*out_nid = m_nid;
fb399b485   zijun_hu   mm/memblock.c: fi...
1107
  			idx_a--;
f1af9d3af   Philipp Hachtmann   mm/memblock: Do s...
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
  			*idx = (u32)idx_a | (u64)idx_b << 32;
  			return;
  		}
  
  		/* scan areas before each reservation */
  		for (; idx_b >= 0; idx_b--) {
  			struct memblock_region *r;
  			phys_addr_t r_start;
  			phys_addr_t r_end;
  
  			r = &type_b->regions[idx_b];
  			r_start = idx_b ? r[-1].base + r[-1].size : 0;
  			r_end = idx_b < type_b->cnt ?
1c4bc43dd   Stefan Agner   mm/memblock: intr...
1121
  				r->base : PHYS_ADDR_MAX;
f1af9d3af   Philipp Hachtmann   mm/memblock: Do s...
1122
1123
1124
1125
  			/*
  			 * if idx_b advanced past idx_a,
  			 * break out to advance idx_a
  			 */
7bd0b0f0d   Tejun Heo   memblock: Reimple...
1126

7bd0b0f0d   Tejun Heo   memblock: Reimple...
1127
1128
1129
1130
1131
1132
1133
1134
1135
  			if (r_end <= m_start)
  				break;
  			/* if the two regions intersect, we're done */
  			if (m_end > r_start) {
  				if (out_start)
  					*out_start = max(m_start, r_start);
  				if (out_end)
  					*out_end = min(m_end, r_end);
  				if (out_nid)
f1af9d3af   Philipp Hachtmann   mm/memblock: Do s...
1136
  					*out_nid = m_nid;
7bd0b0f0d   Tejun Heo   memblock: Reimple...
1137
  				if (m_start >= r_start)
f1af9d3af   Philipp Hachtmann   mm/memblock: Do s...
1138
  					idx_a--;
7bd0b0f0d   Tejun Heo   memblock: Reimple...
1139
  				else
f1af9d3af   Philipp Hachtmann   mm/memblock: Do s...
1140
1141
  					idx_b--;
  				*idx = (u32)idx_a | (u64)idx_b << 32;
7bd0b0f0d   Tejun Heo   memblock: Reimple...
1142
1143
1144
1145
  				return;
  			}
  		}
  	}
f1af9d3af   Philipp Hachtmann   mm/memblock: Do s...
1146
  	/* signal end of iteration */
7bd0b0f0d   Tejun Heo   memblock: Reimple...
1147
1148
  	*idx = ULLONG_MAX;
  }
7c0caeb86   Tejun Heo   memblock: Add opt...
1149
  /*
45e79815b   Chen Chang   mm/memblock.c: fi...
1150
   * Common iterator interface used to define for_each_mem_pfn_range().
7c0caeb86   Tejun Heo   memblock: Add opt...
1151
1152
1153
1154
1155
1156
1157
   */
  void __init_memblock __next_mem_pfn_range(int *idx, int nid,
  				unsigned long *out_start_pfn,
  				unsigned long *out_end_pfn, int *out_nid)
  {
  	struct memblock_type *type = &memblock.memory;
  	struct memblock_region *r;
d622abf74   Mike Rapoport   mm: memblock: rep...
1158
  	int r_nid;
7c0caeb86   Tejun Heo   memblock: Add opt...
1159
1160
1161
  
  	while (++*idx < type->cnt) {
  		r = &type->regions[*idx];
d622abf74   Mike Rapoport   mm: memblock: rep...
1162
  		r_nid = memblock_get_region_node(r);
7c0caeb86   Tejun Heo   memblock: Add opt...
1163
1164
1165
  
  		if (PFN_UP(r->base) >= PFN_DOWN(r->base + r->size))
  			continue;
d622abf74   Mike Rapoport   mm: memblock: rep...
1166
  		if (nid == MAX_NUMNODES || nid == r_nid)
7c0caeb86   Tejun Heo   memblock: Add opt...
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
  			break;
  	}
  	if (*idx >= type->cnt) {
  		*idx = -1;
  		return;
  	}
  
  	if (out_start_pfn)
  		*out_start_pfn = PFN_UP(r->base);
  	if (out_end_pfn)
  		*out_end_pfn = PFN_DOWN(r->base + r->size);
  	if (out_nid)
d622abf74   Mike Rapoport   mm: memblock: rep...
1179
  		*out_nid = r_nid;
7c0caeb86   Tejun Heo   memblock: Add opt...
1180
1181
1182
1183
1184
1185
  }
  
  /**
   * memblock_set_node - set node ID on memblock regions
   * @base: base of area to set node ID for
   * @size: size of area to set node ID for
e7e8de591   Tang Chen   memblock: make me...
1186
   * @type: memblock type to set node ID for
7c0caeb86   Tejun Heo   memblock: Add opt...
1187
1188
   * @nid: node ID to set
   *
47cec4432   Mike Rapoport   docs/mm: memblock...
1189
   * Set the nid of memblock @type regions in [@base, @base + @size) to @nid.
7c0caeb86   Tejun Heo   memblock: Add opt...
1190
1191
   * Regions which cross the area boundaries are split as necessary.
   *
47cec4432   Mike Rapoport   docs/mm: memblock...
1192
   * Return:
7c0caeb86   Tejun Heo   memblock: Add opt...
1193
1194
1195
   * 0 on success, -errno on failure.
   */
  int __init_memblock memblock_set_node(phys_addr_t base, phys_addr_t size,
e7e8de591   Tang Chen   memblock: make me...
1196
  				      struct memblock_type *type, int nid)
7c0caeb86   Tejun Heo   memblock: Add opt...
1197
  {
3f08a302f   Mike Rapoport   mm: remove CONFIG...
1198
  #ifdef CONFIG_NEED_MULTIPLE_NODES
6a9ceb31c   Tejun Heo   memblock: Separat...
1199
1200
  	int start_rgn, end_rgn;
  	int i, ret;
7c0caeb86   Tejun Heo   memblock: Add opt...
1201

6a9ceb31c   Tejun Heo   memblock: Separat...
1202
1203
1204
  	ret = memblock_isolate_range(type, base, size, &start_rgn, &end_rgn);
  	if (ret)
  		return ret;
7c0caeb86   Tejun Heo   memblock: Add opt...
1205

6a9ceb31c   Tejun Heo   memblock: Separat...
1206
  	for (i = start_rgn; i < end_rgn; i++)
e9d24ad30   Wanpeng Li   mm/memblock: use ...
1207
  		memblock_set_region_node(&type->regions[i], nid);
7c0caeb86   Tejun Heo   memblock: Add opt...
1208
1209
  
  	memblock_merge_regions(type);
3f08a302f   Mike Rapoport   mm: remove CONFIG...
1210
  #endif
7c0caeb86   Tejun Heo   memblock: Add opt...
1211
1212
  	return 0;
  }
3f08a302f   Mike Rapoport   mm: remove CONFIG...
1213

837566e7e   Alexander Duyck   mm: implement new...
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
  #ifdef CONFIG_DEFERRED_STRUCT_PAGE_INIT
  /**
   * __next_mem_pfn_range_in_zone - iterator for for_each_*_range_in_zone()
   *
   * @idx: pointer to u64 loop variable
   * @zone: zone in which all of the memory blocks reside
   * @out_spfn: ptr to ulong for start pfn of the range, can be %NULL
   * @out_epfn: ptr to ulong for end pfn of the range, can be %NULL
   *
   * This function is meant to be a zone/pfn specific wrapper for the
   * for_each_mem_range type iterators. Specifically they are used in the
   * deferred memory init routines and as such we were duplicating much of
   * this logic throughout the code. So instead of having it in multiple
   * locations it seemed like it would make more sense to centralize this to
   * one new iterator that does everything they need.
   */
  void __init_memblock
  __next_mem_pfn_range_in_zone(u64 *idx, struct zone *zone,
  			     unsigned long *out_spfn, unsigned long *out_epfn)
  {
  	int zone_nid = zone_to_nid(zone);
  	phys_addr_t spa, epa;
  	int nid;
  
  	__next_mem_range(idx, zone_nid, MEMBLOCK_NONE,
  			 &memblock.memory, &memblock.reserved,
  			 &spa, &epa, &nid);
  
  	while (*idx != U64_MAX) {
  		unsigned long epfn = PFN_DOWN(epa);
  		unsigned long spfn = PFN_UP(spa);
  
  		/*
  		 * Verify the end is at least past the start of the zone and
  		 * that we have at least one PFN to initialize.
  		 */
  		if (zone->zone_start_pfn < epfn && spfn < epfn) {
  			/* if we went too far just stop searching */
  			if (zone_end_pfn(zone) <= spfn) {
  				*idx = U64_MAX;
  				break;
  			}
  
  			if (out_spfn)
  				*out_spfn = max(zone->zone_start_pfn, spfn);
  			if (out_epfn)
  				*out_epfn = min(zone_end_pfn(zone), epfn);
  
  			return;
  		}
  
  		__next_mem_range(idx, zone_nid, MEMBLOCK_NONE,
  				 &memblock.memory, &memblock.reserved,
  				 &spa, &epa, &nid);
  	}
  
  	/* signal end of iteration */
  	if (out_spfn)
  		*out_spfn = ULONG_MAX;
  	if (out_epfn)
  		*out_epfn = 0;
  }
  
  #endif /* CONFIG_DEFERRED_STRUCT_PAGE_INIT */
7c0caeb86   Tejun Heo   memblock: Add opt...
1278

92d12f954   Mike Rapoport   memblock: refacto...
1279
1280
1281
1282
1283
1284
1285
  /**
   * memblock_alloc_range_nid - allocate boot memory block
   * @size: size of memory block to be allocated in bytes
   * @align: alignment of the region and block's size
   * @start: the lower bound of the memory region to allocate (phys address)
   * @end: the upper bound of the memory region to allocate (phys address)
   * @nid: nid of the free area to find, %NUMA_NO_NODE for any node
0ac398b17   Yunfeng Ye   mm: support membl...
1286
   * @exact_nid: control the allocation fall back to other nodes
92d12f954   Mike Rapoport   memblock: refacto...
1287
1288
   *
   * The allocation is performed from memory region limited by
95830666b   Cao jin   mm/memblock: corr...
1289
   * memblock.current_limit if @end == %MEMBLOCK_ALLOC_ACCESSIBLE.
92d12f954   Mike Rapoport   memblock: refacto...
1290
   *
0ac398b17   Yunfeng Ye   mm: support membl...
1291
1292
   * If the specified node can not hold the requested memory and @exact_nid
   * is false, the allocation falls back to any node in the system.
92d12f954   Mike Rapoport   memblock: refacto...
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
   *
   * For systems with memory mirroring, the allocation is attempted first
   * from the regions with mirroring enabled and then retried from any
   * memory region.
   *
   * In addition, function sets the min_count to 0 using kmemleak_alloc_phys for
   * allocated boot memory block, so that it is never reported as leaks.
   *
   * Return:
   * Physical address of allocated memory block on success, %0 on failure.
   */
8676af1ff   Aslan Bakirov   mm: cma: NUMA nod...
1304
  phys_addr_t __init memblock_alloc_range_nid(phys_addr_t size,
2bfc2862c   Akinobu Mita   memblock: introdu...
1305
  					phys_addr_t align, phys_addr_t start,
0ac398b17   Yunfeng Ye   mm: support membl...
1306
1307
  					phys_addr_t end, int nid,
  					bool exact_nid)
95f72d1ed   Yinghai Lu   lmb: rename to me...
1308
  {
92d12f954   Mike Rapoport   memblock: refacto...
1309
  	enum memblock_flags flags = choose_memblock_flags();
6ed311b28   Benjamin Herrenschmidt   memblock: Move fu...
1310
  	phys_addr_t found;
95f72d1ed   Yinghai Lu   lmb: rename to me...
1311

92d12f954   Mike Rapoport   memblock: refacto...
1312
1313
1314
  	if (WARN_ONCE(nid == MAX_NUMNODES, "Usage of MAX_NUMNODES is deprecated. Use NUMA_NO_NODE instead
  "))
  		nid = NUMA_NO_NODE;
2f770806f   Mike Rapoport   mm/memblock.c: wa...
1315
1316
1317
1318
1319
  	if (!align) {
  		/* Can't use WARNs this early in boot on powerpc */
  		dump_stack();
  		align = SMP_CACHE_BYTES;
  	}
92d12f954   Mike Rapoport   memblock: refacto...
1320
  again:
fc6daaf93   Tony Luck   mm/memblock: add ...
1321
1322
  	found = memblock_find_in_range_node(size, align, start, end, nid,
  					    flags);
92d12f954   Mike Rapoport   memblock: refacto...
1323
1324
  	if (found && !memblock_reserve(found, size))
  		goto done;
0ac398b17   Yunfeng Ye   mm: support membl...
1325
  	if (nid != NUMA_NO_NODE && !exact_nid) {
92d12f954   Mike Rapoport   memblock: refacto...
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
  		found = memblock_find_in_range_node(size, align, start,
  						    end, NUMA_NO_NODE,
  						    flags);
  		if (found && !memblock_reserve(found, size))
  			goto done;
  	}
  
  	if (flags & MEMBLOCK_MIRROR) {
  		flags &= ~MEMBLOCK_MIRROR;
  		pr_warn("Could not allocate %pap bytes of mirrored memory
  ",
  			&size);
  		goto again;
  	}
  
  	return 0;
  
  done:
  	/* Skip kmemleak for kasan_init() due to high volume. */
  	if (end != MEMBLOCK_ALLOC_KASAN)
aedf95ea0   Catalin Marinas   mm/memblock.c: ca...
1346
  		/*
92d12f954   Mike Rapoport   memblock: refacto...
1347
1348
1349
1350
  		 * The min_count is set to 0 so that memblock allocated
  		 * blocks are never reported as leaks. This is because many
  		 * of these blocks are only referred via the physical
  		 * address which is not looked up by kmemleak.
aedf95ea0   Catalin Marinas   mm/memblock.c: ca...
1351
  		 */
9099daed9   Catalin Marinas   mm: kmemleak: avo...
1352
  		kmemleak_alloc_phys(found, size, 0, 0);
92d12f954   Mike Rapoport   memblock: refacto...
1353
1354
  
  	return found;
95f72d1ed   Yinghai Lu   lmb: rename to me...
1355
  }
a2974133b   Mike Rapoport   mm: memblock: upd...
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
  /**
   * memblock_phys_alloc_range - allocate a memory block inside specified range
   * @size: size of memory block to be allocated in bytes
   * @align: alignment of the region and block's size
   * @start: the lower bound of the memory region to allocate (physical address)
   * @end: the upper bound of the memory region to allocate (physical address)
   *
   * Allocate @size bytes in the between @start and @end.
   *
   * Return: physical address of the allocated memory block on success,
   * %0 on failure.
   */
8a770c2a8   Mike Rapoport   memblock: emphasi...
1368
1369
1370
1371
  phys_addr_t __init memblock_phys_alloc_range(phys_addr_t size,
  					     phys_addr_t align,
  					     phys_addr_t start,
  					     phys_addr_t end)
2bfc2862c   Akinobu Mita   memblock: introdu...
1372
  {
0ac398b17   Yunfeng Ye   mm: support membl...
1373
1374
  	return memblock_alloc_range_nid(size, align, start, end, NUMA_NO_NODE,
  					false);
7bd0b0f0d   Tejun Heo   memblock: Reimple...
1375
  }
a2974133b   Mike Rapoport   mm: memblock: upd...
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
  /**
   * memblock_phys_alloc_try_nid - allocate a memory block from specified MUMA node
   * @size: size of memory block to be allocated in bytes
   * @align: alignment of the region and block's size
   * @nid: nid of the free area to find, %NUMA_NO_NODE for any node
   *
   * Allocates memory block from the specified NUMA node. If the node
   * has no available memory, attempts to allocated from any node in the
   * system.
   *
   * Return: physical address of the allocated memory block on success,
   * %0 on failure.
   */
9a8dd708d   Mike Rapoport   memblock: rename ...
1389
  phys_addr_t __init memblock_phys_alloc_try_nid(phys_addr_t size, phys_addr_t align, int nid)
9d1e24928   Benjamin Herrenschmidt   memblock: Separat...
1390
  {
337555744   Mike Rapoport   memblock: membloc...
1391
  	return memblock_alloc_range_nid(size, align, 0,
0ac398b17   Yunfeng Ye   mm: support membl...
1392
  					MEMBLOCK_ALLOC_ACCESSIBLE, nid, false);
95f72d1ed   Yinghai Lu   lmb: rename to me...
1393
  }
26f09e9b3   Santosh Shilimkar   mm/memblock: add ...
1394
  /**
eb31d559f   Mike Rapoport   memblock: remove ...
1395
   * memblock_alloc_internal - allocate boot memory block
26f09e9b3   Santosh Shilimkar   mm/memblock: add ...
1396
1397
1398
1399
1400
   * @size: size of memory block to be allocated in bytes
   * @align: alignment of the region and block's size
   * @min_addr: the lower bound of the memory region to allocate (phys address)
   * @max_addr: the upper bound of the memory region to allocate (phys address)
   * @nid: nid of the free area to find, %NUMA_NO_NODE for any node
0ac398b17   Yunfeng Ye   mm: support membl...
1401
   * @exact_nid: control the allocation fall back to other nodes
26f09e9b3   Santosh Shilimkar   mm/memblock: add ...
1402
   *
92d12f954   Mike Rapoport   memblock: refacto...
1403
1404
   * Allocates memory block using memblock_alloc_range_nid() and
   * converts the returned physical address to virtual.
26f09e9b3   Santosh Shilimkar   mm/memblock: add ...
1405
   *
92d12f954   Mike Rapoport   memblock: refacto...
1406
1407
1408
1409
   * The @min_addr limit is dropped if it can not be satisfied and the allocation
   * will fall back to memory below @min_addr. Other constraints, such
   * as node and mirrored memory will be handled again in
   * memblock_alloc_range_nid().
26f09e9b3   Santosh Shilimkar   mm/memblock: add ...
1410
   *
47cec4432   Mike Rapoport   docs/mm: memblock...
1411
   * Return:
26f09e9b3   Santosh Shilimkar   mm/memblock: add ...
1412
1413
   * Virtual address of allocated memory block on success, NULL on failure.
   */
eb31d559f   Mike Rapoport   memblock: remove ...
1414
  static void * __init memblock_alloc_internal(
26f09e9b3   Santosh Shilimkar   mm/memblock: add ...
1415
1416
  				phys_addr_t size, phys_addr_t align,
  				phys_addr_t min_addr, phys_addr_t max_addr,
0ac398b17   Yunfeng Ye   mm: support membl...
1417
  				int nid, bool exact_nid)
26f09e9b3   Santosh Shilimkar   mm/memblock: add ...
1418
1419
  {
  	phys_addr_t alloc;
26f09e9b3   Santosh Shilimkar   mm/memblock: add ...
1420
1421
1422
1423
  
  	/*
  	 * Detect any accidental use of these APIs after slab is ready, as at
  	 * this moment memblock may be deinitialized already and its
c6ffc5ca8   Mike Rapoport   memblock: rename ...
1424
  	 * internal data may be destroyed (after execution of memblock_free_all)
26f09e9b3   Santosh Shilimkar   mm/memblock: add ...
1425
1426
1427
  	 */
  	if (WARN_ON_ONCE(slab_is_available()))
  		return kzalloc_node(size, GFP_NOWAIT, nid);
f3057ad76   Mike Rapoport   mm: memblock: do ...
1428
1429
  	if (max_addr > memblock.current_limit)
  		max_addr = memblock.current_limit;
0ac398b17   Yunfeng Ye   mm: support membl...
1430
1431
  	alloc = memblock_alloc_range_nid(size, align, min_addr, max_addr, nid,
  					exact_nid);
26f09e9b3   Santosh Shilimkar   mm/memblock: add ...
1432

92d12f954   Mike Rapoport   memblock: refacto...
1433
1434
  	/* retry allocation without lower limit */
  	if (!alloc && min_addr)
0ac398b17   Yunfeng Ye   mm: support membl...
1435
1436
  		alloc = memblock_alloc_range_nid(size, align, 0, max_addr, nid,
  						exact_nid);
26f09e9b3   Santosh Shilimkar   mm/memblock: add ...
1437

92d12f954   Mike Rapoport   memblock: refacto...
1438
1439
  	if (!alloc)
  		return NULL;
26f09e9b3   Santosh Shilimkar   mm/memblock: add ...
1440

92d12f954   Mike Rapoport   memblock: refacto...
1441
  	return phys_to_virt(alloc);
26f09e9b3   Santosh Shilimkar   mm/memblock: add ...
1442
1443
1444
  }
  
  /**
0ac398b17   Yunfeng Ye   mm: support membl...
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
   * memblock_alloc_exact_nid_raw - allocate boot memory block on the exact node
   * without zeroing memory
   * @size: size of memory block to be allocated in bytes
   * @align: alignment of the region and block's size
   * @min_addr: the lower bound of the memory region from where the allocation
   *	  is preferred (phys address)
   * @max_addr: the upper bound of the memory region from where the allocation
   *	      is preferred (phys address), or %MEMBLOCK_ALLOC_ACCESSIBLE to
   *	      allocate only from memory limited by memblock.current_limit value
   * @nid: nid of the free area to find, %NUMA_NO_NODE for any node
   *
   * Public function, provides additional debug information (including caller
   * info), if enabled. Does not zero allocated memory.
   *
   * Return:
   * Virtual address of allocated memory block on success, NULL on failure.
   */
  void * __init memblock_alloc_exact_nid_raw(
  			phys_addr_t size, phys_addr_t align,
  			phys_addr_t min_addr, phys_addr_t max_addr,
  			int nid)
  {
  	void *ptr;
  
  	memblock_dbg("%s: %llu bytes align=0x%llx nid=%d from=%pa max_addr=%pa %pS
  ",
  		     __func__, (u64)size, (u64)align, nid, &min_addr,
  		     &max_addr, (void *)_RET_IP_);
  
  	ptr = memblock_alloc_internal(size, align,
  					   min_addr, max_addr, nid, true);
  	if (ptr && size > 0)
  		page_init_poison(ptr, size);
  
  	return ptr;
  }
  
  /**
eb31d559f   Mike Rapoport   memblock: remove ...
1483
   * memblock_alloc_try_nid_raw - allocate boot memory block without zeroing
ea1f5f371   Pavel Tatashin   mm: define memblo...
1484
1485
1486
1487
1488
1489
   * memory and without panicking
   * @size: size of memory block to be allocated in bytes
   * @align: alignment of the region and block's size
   * @min_addr: the lower bound of the memory region from where the allocation
   *	  is preferred (phys address)
   * @max_addr: the upper bound of the memory region from where the allocation
97ad1087e   Mike Rapoport   memblock: replace...
1490
   *	      is preferred (phys address), or %MEMBLOCK_ALLOC_ACCESSIBLE to
ea1f5f371   Pavel Tatashin   mm: define memblo...
1491
1492
1493
1494
1495
1496
1497
   *	      allocate only from memory limited by memblock.current_limit value
   * @nid: nid of the free area to find, %NUMA_NO_NODE for any node
   *
   * Public function, provides additional debug information (including caller
   * info), if enabled. Does not zero allocated memory, does not panic if request
   * cannot be satisfied.
   *
47cec4432   Mike Rapoport   docs/mm: memblock...
1498
   * Return:
ea1f5f371   Pavel Tatashin   mm: define memblo...
1499
1500
   * Virtual address of allocated memory block on success, NULL on failure.
   */
eb31d559f   Mike Rapoport   memblock: remove ...
1501
  void * __init memblock_alloc_try_nid_raw(
ea1f5f371   Pavel Tatashin   mm: define memblo...
1502
1503
1504
1505
1506
  			phys_addr_t size, phys_addr_t align,
  			phys_addr_t min_addr, phys_addr_t max_addr,
  			int nid)
  {
  	void *ptr;
d75f773c8   Sakari Ailus   treewide: Switch ...
1507
1508
  	memblock_dbg("%s: %llu bytes align=0x%llx nid=%d from=%pa max_addr=%pa %pS
  ",
a36aab890   Mike Rapoport   mm/memblock.c: re...
1509
1510
  		     __func__, (u64)size, (u64)align, nid, &min_addr,
  		     &max_addr, (void *)_RET_IP_);
ea1f5f371   Pavel Tatashin   mm: define memblo...
1511

eb31d559f   Mike Rapoport   memblock: remove ...
1512
  	ptr = memblock_alloc_internal(size, align,
0ac398b17   Yunfeng Ye   mm: support membl...
1513
  					   min_addr, max_addr, nid, false);
ea1f5f371   Pavel Tatashin   mm: define memblo...
1514
  	if (ptr && size > 0)
f682a97a0   Alexander Duyck   mm: provide kerne...
1515
  		page_init_poison(ptr, size);
ea1f5f371   Pavel Tatashin   mm: define memblo...
1516
1517
1518
1519
  	return ptr;
  }
  
  /**
c0dbe825a   Mike Rapoport   memblock: membloc...
1520
   * memblock_alloc_try_nid - allocate boot memory block
26f09e9b3   Santosh Shilimkar   mm/memblock: add ...
1521
1522
1523
1524
1525
   * @size: size of memory block to be allocated in bytes
   * @align: alignment of the region and block's size
   * @min_addr: the lower bound of the memory region from where the allocation
   *	  is preferred (phys address)
   * @max_addr: the upper bound of the memory region from where the allocation
97ad1087e   Mike Rapoport   memblock: replace...
1526
   *	      is preferred (phys address), or %MEMBLOCK_ALLOC_ACCESSIBLE to
26f09e9b3   Santosh Shilimkar   mm/memblock: add ...
1527
1528
1529
   *	      allocate only from memory limited by memblock.current_limit value
   * @nid: nid of the free area to find, %NUMA_NO_NODE for any node
   *
c0dbe825a   Mike Rapoport   memblock: membloc...
1530
1531
   * Public function, provides additional debug information (including caller
   * info), if enabled. This function zeroes the allocated memory.
26f09e9b3   Santosh Shilimkar   mm/memblock: add ...
1532
   *
47cec4432   Mike Rapoport   docs/mm: memblock...
1533
   * Return:
26f09e9b3   Santosh Shilimkar   mm/memblock: add ...
1534
1535
   * Virtual address of allocated memory block on success, NULL on failure.
   */
eb31d559f   Mike Rapoport   memblock: remove ...
1536
  void * __init memblock_alloc_try_nid(
26f09e9b3   Santosh Shilimkar   mm/memblock: add ...
1537
1538
1539
1540
1541
  			phys_addr_t size, phys_addr_t align,
  			phys_addr_t min_addr, phys_addr_t max_addr,
  			int nid)
  {
  	void *ptr;
d75f773c8   Sakari Ailus   treewide: Switch ...
1542
1543
  	memblock_dbg("%s: %llu bytes align=0x%llx nid=%d from=%pa max_addr=%pa %pS
  ",
a36aab890   Mike Rapoport   mm/memblock.c: re...
1544
1545
  		     __func__, (u64)size, (u64)align, nid, &min_addr,
  		     &max_addr, (void *)_RET_IP_);
eb31d559f   Mike Rapoport   memblock: remove ...
1546
  	ptr = memblock_alloc_internal(size, align,
0ac398b17   Yunfeng Ye   mm: support membl...
1547
  					   min_addr, max_addr, nid, false);
c0dbe825a   Mike Rapoport   memblock: membloc...
1548
  	if (ptr)
ea1f5f371   Pavel Tatashin   mm: define memblo...
1549
  		memset(ptr, 0, size);
26f09e9b3   Santosh Shilimkar   mm/memblock: add ...
1550

c0dbe825a   Mike Rapoport   memblock: membloc...
1551
  	return ptr;
26f09e9b3   Santosh Shilimkar   mm/memblock: add ...
1552
1553
1554
  }
  
  /**
a2974133b   Mike Rapoport   mm: memblock: upd...
1555
   * __memblock_free_late - free pages directly to buddy allocator
48a833cc7   Mike Rapoport   docs/mm: memblock...
1556
   * @base: phys starting address of the  boot memory block
26f09e9b3   Santosh Shilimkar   mm/memblock: add ...
1557
1558
   * @size: size of the boot memory block in bytes
   *
a2974133b   Mike Rapoport   mm: memblock: upd...
1559
   * This is only useful when the memblock allocator has already been torn
26f09e9b3   Santosh Shilimkar   mm/memblock: add ...
1560
   * down, but we are still initializing the system.  Pages are released directly
a2974133b   Mike Rapoport   mm: memblock: upd...
1561
   * to the buddy allocator.
26f09e9b3   Santosh Shilimkar   mm/memblock: add ...
1562
1563
1564
   */
  void __init __memblock_free_late(phys_addr_t base, phys_addr_t size)
  {
a36aab890   Mike Rapoport   mm/memblock.c: re...
1565
  	phys_addr_t cursor, end;
26f09e9b3   Santosh Shilimkar   mm/memblock: add ...
1566

a36aab890   Mike Rapoport   mm/memblock.c: re...
1567
  	end = base + size - 1;
d75f773c8   Sakari Ailus   treewide: Switch ...
1568
1569
  	memblock_dbg("%s: [%pa-%pa] %pS
  ",
a36aab890   Mike Rapoport   mm/memblock.c: re...
1570
  		     __func__, &base, &end, (void *)_RET_IP_);
9099daed9   Catalin Marinas   mm: kmemleak: avo...
1571
  	kmemleak_free_part_phys(base, size);
26f09e9b3   Santosh Shilimkar   mm/memblock: add ...
1572
1573
1574
1575
  	cursor = PFN_UP(base);
  	end = PFN_DOWN(base + size);
  
  	for (; cursor < end; cursor++) {
7c2ee349c   Mike Rapoport   memblock: rename ...
1576
  		memblock_free_pages(pfn_to_page(cursor), cursor, 0);
ca79b0c21   Arun KS   mm: convert total...
1577
  		totalram_pages_inc();
26f09e9b3   Santosh Shilimkar   mm/memblock: add ...
1578
1579
  	}
  }
9d1e24928   Benjamin Herrenschmidt   memblock: Separat...
1580
1581
1582
1583
  
  /*
   * Remaining API functions
   */
1f1ffb8a1   David Gibson   memblock: don't m...
1584
  phys_addr_t __init_memblock memblock_phys_mem_size(void)
95f72d1ed   Yinghai Lu   lmb: rename to me...
1585
  {
1440c4e2c   Tejun Heo   memblock: Track t...
1586
  	return memblock.memory.total_size;
95f72d1ed   Yinghai Lu   lmb: rename to me...
1587
  }
8907de5dc   Srikar Dronamraju   mm/memblock.c: ex...
1588
1589
1590
1591
  phys_addr_t __init_memblock memblock_reserved_size(void)
  {
  	return memblock.reserved.total_size;
  }
0a93ebef6   Sam Ravnborg   memblock: add mem...
1592
1593
1594
1595
1596
  /* lowest address */
  phys_addr_t __init_memblock memblock_start_of_DRAM(void)
  {
  	return memblock.memory.regions[0].base;
  }
10d064398   Yinghai Lu   memblock: Option ...
1597
  phys_addr_t __init_memblock memblock_end_of_DRAM(void)
95f72d1ed   Yinghai Lu   lmb: rename to me...
1598
1599
  {
  	int idx = memblock.memory.cnt - 1;
e3239ff92   Benjamin Herrenschmidt   memblock: Rename ...
1600
  	return (memblock.memory.regions[idx].base + memblock.memory.regions[idx].size);
95f72d1ed   Yinghai Lu   lmb: rename to me...
1601
  }
a571d4eb5   Dennis Chen   mm/memblock.c: ad...
1602
  static phys_addr_t __init_memblock __find_max_addr(phys_addr_t limit)
95f72d1ed   Yinghai Lu   lmb: rename to me...
1603
  {
1c4bc43dd   Stefan Agner   mm/memblock: intr...
1604
  	phys_addr_t max_addr = PHYS_ADDR_MAX;
136199f0a   Emil Medve   memblock: use for...
1605
  	struct memblock_region *r;
95f72d1ed   Yinghai Lu   lmb: rename to me...
1606

a571d4eb5   Dennis Chen   mm/memblock.c: ad...
1607
1608
1609
  	/*
  	 * translate the memory @limit size into the max address within one of
  	 * the memory memblock regions, if the @limit exceeds the total size
1c4bc43dd   Stefan Agner   mm/memblock: intr...
1610
  	 * of those regions, max_addr will keep original value PHYS_ADDR_MAX
a571d4eb5   Dennis Chen   mm/memblock.c: ad...
1611
  	 */
cc6de1680   Mike Rapoport   memblock: use sep...
1612
  	for_each_mem_region(r) {
c0ce8fef5   Tejun Heo   memblock: Reimple...
1613
1614
1615
  		if (limit <= r->size) {
  			max_addr = r->base + limit;
  			break;
95f72d1ed   Yinghai Lu   lmb: rename to me...
1616
  		}
c0ce8fef5   Tejun Heo   memblock: Reimple...
1617
  		limit -= r->size;
95f72d1ed   Yinghai Lu   lmb: rename to me...
1618
  	}
c0ce8fef5   Tejun Heo   memblock: Reimple...
1619

a571d4eb5   Dennis Chen   mm/memblock.c: ad...
1620
1621
1622
1623
1624
  	return max_addr;
  }
  
  void __init memblock_enforce_memory_limit(phys_addr_t limit)
  {
49aef7175   Colin Ian King   mm/memblock.c: re...
1625
  	phys_addr_t max_addr;
a571d4eb5   Dennis Chen   mm/memblock.c: ad...
1626
1627
1628
1629
1630
1631
1632
  
  	if (!limit)
  		return;
  
  	max_addr = __find_max_addr(limit);
  
  	/* @limit exceeds the total size of the memory, do nothing */
1c4bc43dd   Stefan Agner   mm/memblock: intr...
1633
  	if (max_addr == PHYS_ADDR_MAX)
a571d4eb5   Dennis Chen   mm/memblock.c: ad...
1634
  		return;
c0ce8fef5   Tejun Heo   memblock: Reimple...
1635
  	/* truncate both memory and reserved regions */
f1af9d3af   Philipp Hachtmann   mm/memblock: Do s...
1636
  	memblock_remove_range(&memblock.memory, max_addr,
1c4bc43dd   Stefan Agner   mm/memblock: intr...
1637
  			      PHYS_ADDR_MAX);
f1af9d3af   Philipp Hachtmann   mm/memblock: Do s...
1638
  	memblock_remove_range(&memblock.reserved, max_addr,
1c4bc43dd   Stefan Agner   mm/memblock: intr...
1639
  			      PHYS_ADDR_MAX);
95f72d1ed   Yinghai Lu   lmb: rename to me...
1640
  }
c9ca9b4e2   AKASHI Takahiro   memblock: add mem...
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
  void __init memblock_cap_memory_range(phys_addr_t base, phys_addr_t size)
  {
  	int start_rgn, end_rgn;
  	int i, ret;
  
  	if (!size)
  		return;
  
  	ret = memblock_isolate_range(&memblock.memory, base, size,
  						&start_rgn, &end_rgn);
  	if (ret)
  		return;
  
  	/* remove all the MAP regions */
  	for (i = memblock.memory.cnt - 1; i >= end_rgn; i--)
  		if (!memblock_is_nomap(&memblock.memory.regions[i]))
  			memblock_remove_region(&memblock.memory, i);
  
  	for (i = start_rgn - 1; i >= 0; i--)
  		if (!memblock_is_nomap(&memblock.memory.regions[i]))
  			memblock_remove_region(&memblock.memory, i);
  
  	/* truncate the reserved regions */
  	memblock_remove_range(&memblock.reserved, 0, base);
  	memblock_remove_range(&memblock.reserved,
1c4bc43dd   Stefan Agner   mm/memblock: intr...
1666
  			base + size, PHYS_ADDR_MAX);
c9ca9b4e2   AKASHI Takahiro   memblock: add mem...
1667
  }
a571d4eb5   Dennis Chen   mm/memblock.c: ad...
1668
1669
  void __init memblock_mem_limit_remove_map(phys_addr_t limit)
  {
a571d4eb5   Dennis Chen   mm/memblock.c: ad...
1670
  	phys_addr_t max_addr;
a571d4eb5   Dennis Chen   mm/memblock.c: ad...
1671
1672
1673
1674
1675
1676
1677
  
  	if (!limit)
  		return;
  
  	max_addr = __find_max_addr(limit);
  
  	/* @limit exceeds the total size of the memory, do nothing */
1c4bc43dd   Stefan Agner   mm/memblock: intr...
1678
  	if (max_addr == PHYS_ADDR_MAX)
a571d4eb5   Dennis Chen   mm/memblock.c: ad...
1679
  		return;
c9ca9b4e2   AKASHI Takahiro   memblock: add mem...
1680
  	memblock_cap_memory_range(0, max_addr);
a571d4eb5   Dennis Chen   mm/memblock.c: ad...
1681
  }
cd79481d2   Yinghai Lu   memblock: Annotat...
1682
  static int __init_memblock memblock_search(struct memblock_type *type, phys_addr_t addr)
72d4b0b4e   Benjamin Herrenschmidt   memblock: Impleme...
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
  {
  	unsigned int left = 0, right = type->cnt;
  
  	do {
  		unsigned int mid = (right + left) / 2;
  
  		if (addr < type->regions[mid].base)
  			right = mid;
  		else if (addr >= (type->regions[mid].base +
  				  type->regions[mid].size))
  			left = mid + 1;
  		else
  			return mid;
  	} while (left < right);
  	return -1;
  }
f5a222dc2   Yueyi Li   memblock: annotat...
1699
  bool __init_memblock memblock_is_reserved(phys_addr_t addr)
95f72d1ed   Yinghai Lu   lmb: rename to me...
1700
  {
72d4b0b4e   Benjamin Herrenschmidt   memblock: Impleme...
1701
1702
  	return memblock_search(&memblock.reserved, addr) != -1;
  }
95f72d1ed   Yinghai Lu   lmb: rename to me...
1703

b4ad0c7e0   Yaowei Bai   mm/memblock.c: me...
1704
  bool __init_memblock memblock_is_memory(phys_addr_t addr)
72d4b0b4e   Benjamin Herrenschmidt   memblock: Impleme...
1705
1706
1707
  {
  	return memblock_search(&memblock.memory, addr) != -1;
  }
937f0c267   Yaowei Bai   mm/memblock: memb...
1708
  bool __init_memblock memblock_is_map_memory(phys_addr_t addr)
bf3d3cc58   Ard Biesheuvel   mm/memblock: add ...
1709
1710
1711
1712
1713
1714
1715
  {
  	int i = memblock_search(&memblock.memory, addr);
  
  	if (i == -1)
  		return false;
  	return !memblock_is_nomap(&memblock.memory.regions[i]);
  }
e76b63f80   Yinghai Lu   memblock, numa: b...
1716
1717
1718
1719
  int __init_memblock memblock_search_pfn_nid(unsigned long pfn,
  			 unsigned long *start_pfn, unsigned long *end_pfn)
  {
  	struct memblock_type *type = &memblock.memory;
167632303   Fabian Frederick   mm/memblock.c: us...
1720
  	int mid = memblock_search(type, PFN_PHYS(pfn));
e76b63f80   Yinghai Lu   memblock, numa: b...
1721
1722
1723
  
  	if (mid == -1)
  		return -1;
f7e2f7e89   Fabian Frederick   mm/memblock.c: us...
1724
1725
  	*start_pfn = PFN_DOWN(type->regions[mid].base);
  	*end_pfn = PFN_DOWN(type->regions[mid].base + type->regions[mid].size);
e76b63f80   Yinghai Lu   memblock, numa: b...
1726

d622abf74   Mike Rapoport   mm: memblock: rep...
1727
  	return memblock_get_region_node(&type->regions[mid]);
e76b63f80   Yinghai Lu   memblock, numa: b...
1728
  }
e76b63f80   Yinghai Lu   memblock, numa: b...
1729

eab309494   Stephen Boyd   memblock: Documen...
1730
1731
1732
1733
1734
  /**
   * memblock_is_region_memory - check if a region is a subset of memory
   * @base: base of region to check
   * @size: size of region to check
   *
47cec4432   Mike Rapoport   docs/mm: memblock...
1735
   * Check if the region [@base, @base + @size) is a subset of a memory block.
eab309494   Stephen Boyd   memblock: Documen...
1736
   *
47cec4432   Mike Rapoport   docs/mm: memblock...
1737
   * Return:
eab309494   Stephen Boyd   memblock: Documen...
1738
1739
   * 0 if false, non-zero if true
   */
937f0c267   Yaowei Bai   mm/memblock: memb...
1740
  bool __init_memblock memblock_is_region_memory(phys_addr_t base, phys_addr_t size)
72d4b0b4e   Benjamin Herrenschmidt   memblock: Impleme...
1741
  {
abb65272a   Tomi Valkeinen   memblock: fix mem...
1742
  	int idx = memblock_search(&memblock.memory, base);
eb18f1b5b   Tejun Heo   memblock: Make me...
1743
  	phys_addr_t end = base + memblock_cap_size(base, &size);
72d4b0b4e   Benjamin Herrenschmidt   memblock: Impleme...
1744
1745
  
  	if (idx == -1)
937f0c267   Yaowei Bai   mm/memblock: memb...
1746
  		return false;
ef415ef41   Wei Yang   mm/memblock.c: tr...
1747
  	return (memblock.memory.regions[idx].base +
eb18f1b5b   Tejun Heo   memblock: Make me...
1748
  		 memblock.memory.regions[idx].size) >= end;
95f72d1ed   Yinghai Lu   lmb: rename to me...
1749
  }
eab309494   Stephen Boyd   memblock: Documen...
1750
1751
1752
1753
1754
  /**
   * memblock_is_region_reserved - check if a region intersects reserved memory
   * @base: base of region to check
   * @size: size of region to check
   *
47cec4432   Mike Rapoport   docs/mm: memblock...
1755
1756
   * Check if the region [@base, @base + @size) intersects a reserved
   * memory block.
eab309494   Stephen Boyd   memblock: Documen...
1757
   *
47cec4432   Mike Rapoport   docs/mm: memblock...
1758
   * Return:
c5c5c9d10   Tang Chen   mm/memblock.c: ma...
1759
   * True if they intersect, false if not.
eab309494   Stephen Boyd   memblock: Documen...
1760
   */
c5c5c9d10   Tang Chen   mm/memblock.c: ma...
1761
  bool __init_memblock memblock_is_region_reserved(phys_addr_t base, phys_addr_t size)
95f72d1ed   Yinghai Lu   lmb: rename to me...
1762
  {
eb18f1b5b   Tejun Heo   memblock: Make me...
1763
  	memblock_cap_size(base, &size);
c5c5c9d10   Tang Chen   mm/memblock.c: ma...
1764
  	return memblock_overlaps_region(&memblock.reserved, base, size);
95f72d1ed   Yinghai Lu   lmb: rename to me...
1765
  }
6ede1fd3c   Yinghai Lu   x86, mm: Trim mem...
1766
1767
  void __init_memblock memblock_trim_memory(phys_addr_t align)
  {
6ede1fd3c   Yinghai Lu   x86, mm: Trim mem...
1768
  	phys_addr_t start, end, orig_start, orig_end;
136199f0a   Emil Medve   memblock: use for...
1769
  	struct memblock_region *r;
6ede1fd3c   Yinghai Lu   x86, mm: Trim mem...
1770

cc6de1680   Mike Rapoport   memblock: use sep...
1771
  	for_each_mem_region(r) {
136199f0a   Emil Medve   memblock: use for...
1772
1773
  		orig_start = r->base;
  		orig_end = r->base + r->size;
6ede1fd3c   Yinghai Lu   x86, mm: Trim mem...
1774
1775
1776
1777
1778
1779
1780
  		start = round_up(orig_start, align);
  		end = round_down(orig_end, align);
  
  		if (start == orig_start && end == orig_end)
  			continue;
  
  		if (start < end) {
136199f0a   Emil Medve   memblock: use for...
1781
1782
  			r->base = start;
  			r->size = end - start;
6ede1fd3c   Yinghai Lu   x86, mm: Trim mem...
1783
  		} else {
136199f0a   Emil Medve   memblock: use for...
1784
1785
1786
  			memblock_remove_region(&memblock.memory,
  					       r - memblock.memory.regions);
  			r--;
6ede1fd3c   Yinghai Lu   x86, mm: Trim mem...
1787
1788
1789
  		}
  	}
  }
e63075a3c   Benjamin Herrenschmidt   memblock: Introdu...
1790

3661ca66a   Yinghai Lu   memblock: Fix sec...
1791
  void __init_memblock memblock_set_current_limit(phys_addr_t limit)
e63075a3c   Benjamin Herrenschmidt   memblock: Introdu...
1792
1793
1794
  {
  	memblock.current_limit = limit;
  }
fec510141   Laura Abbott   ARM: 7993/1: mm/m...
1795
1796
1797
1798
  phys_addr_t __init_memblock memblock_get_current_limit(void)
  {
  	return memblock.current_limit;
  }
0262d9c84   Heiko Carstens   memblock: embed m...
1799
  static void __init_memblock memblock_dump(struct memblock_type *type)
6ed311b28   Benjamin Herrenschmidt   memblock: Move fu...
1800
  {
5d63f81c9   Miles Chen   mm/memblock.c: re...
1801
  	phys_addr_t base, end, size;
e1720fee2   Mike Rapoport   mm/memblock: add ...
1802
  	enum memblock_flags flags;
8c9c1701c   Alexander Kuleshov   mm/memblock: intr...
1803
1804
  	int idx;
  	struct memblock_region *rgn;
6ed311b28   Benjamin Herrenschmidt   memblock: Move fu...
1805

0262d9c84   Heiko Carstens   memblock: embed m...
1806
1807
  	pr_info(" %s.cnt  = 0x%lx
  ", type->name, type->cnt);
6ed311b28   Benjamin Herrenschmidt   memblock: Move fu...
1808

66e8b438b   Gioh Kim   mm/memblock.c: ma...
1809
  	for_each_memblock_type(idx, type, rgn) {
7c0caeb86   Tejun Heo   memblock: Add opt...
1810
1811
1812
1813
  		char nid_buf[32] = "";
  
  		base = rgn->base;
  		size = rgn->size;
5d63f81c9   Miles Chen   mm/memblock.c: re...
1814
  		end = base + size - 1;
66a207572   Tang Chen   memblock, numa: i...
1815
  		flags = rgn->flags;
3f08a302f   Mike Rapoport   mm: remove CONFIG...
1816
  #ifdef CONFIG_NEED_MULTIPLE_NODES
7c0caeb86   Tejun Heo   memblock: Add opt...
1817
1818
1819
1820
  		if (memblock_get_region_node(rgn) != MAX_NUMNODES)
  			snprintf(nid_buf, sizeof(nid_buf), " on node %d",
  				 memblock_get_region_node(rgn));
  #endif
e1720fee2   Mike Rapoport   mm/memblock: add ...
1821
1822
  		pr_info(" %s[%#x]\t[%pa-%pa], %pa bytes%s flags: %#x
  ",
0262d9c84   Heiko Carstens   memblock: embed m...
1823
  			type->name, idx, &base, &end, &size, nid_buf, flags);
6ed311b28   Benjamin Herrenschmidt   memblock: Move fu...
1824
1825
  	}
  }
87c55870f   Mike Rapoport   memblock: make me...
1826
  static void __init_memblock __memblock_dump_all(void)
6ed311b28   Benjamin Herrenschmidt   memblock: Move fu...
1827
  {
6ed311b28   Benjamin Herrenschmidt   memblock: Move fu...
1828
1829
  	pr_info("MEMBLOCK configuration:
  ");
5d63f81c9   Miles Chen   mm/memblock.c: re...
1830
1831
1832
1833
  	pr_info(" memory size = %pa reserved size = %pa
  ",
  		&memblock.memory.total_size,
  		&memblock.reserved.total_size);
6ed311b28   Benjamin Herrenschmidt   memblock: Move fu...
1834

0262d9c84   Heiko Carstens   memblock: embed m...
1835
1836
  	memblock_dump(&memblock.memory);
  	memblock_dump(&memblock.reserved);
409efd4c9   Heiko Carstens   memblock: also du...
1837
  #ifdef CONFIG_HAVE_MEMBLOCK_PHYS_MAP
776499058   David Hildenbrand   mm/memblock: expo...
1838
  	memblock_dump(&physmem);
409efd4c9   Heiko Carstens   memblock: also du...
1839
  #endif
6ed311b28   Benjamin Herrenschmidt   memblock: Move fu...
1840
  }
87c55870f   Mike Rapoport   memblock: make me...
1841
1842
1843
1844
1845
  void __init_memblock memblock_dump_all(void)
  {
  	if (memblock_debug)
  		__memblock_dump_all();
  }
1aadc0560   Tejun Heo   memblock: s/membl...
1846
  void __init memblock_allow_resize(void)
6ed311b28   Benjamin Herrenschmidt   memblock: Move fu...
1847
  {
142b45a72   Benjamin Herrenschmidt   memblock: Add arr...
1848
  	memblock_can_resize = 1;
6ed311b28   Benjamin Herrenschmidt   memblock: Move fu...
1849
  }
6ed311b28   Benjamin Herrenschmidt   memblock: Move fu...
1850
1851
1852
1853
1854
1855
1856
  static int __init early_memblock(char *p)
  {
  	if (p && strstr(p, "debug"))
  		memblock_debug = 1;
  	return 0;
  }
  early_param("memblock", early_memblock);
bda49a811   Mike Rapoport   mm: remove nobootmem
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
  static void __init __free_pages_memory(unsigned long start, unsigned long end)
  {
  	int order;
  
  	while (start < end) {
  		order = min(MAX_ORDER - 1UL, __ffs(start));
  
  		while (start + (1UL << order) > end)
  			order--;
  
  		memblock_free_pages(pfn_to_page(start), start, order);
  
  		start += (1UL << order);
  	}
  }
  
  static unsigned long __init __free_memory_core(phys_addr_t start,
  				 phys_addr_t end)
  {
  	unsigned long start_pfn = PFN_UP(start);
  	unsigned long end_pfn = min_t(unsigned long,
  				      PFN_DOWN(end), max_low_pfn);
  
  	if (start_pfn >= end_pfn)
  		return 0;
  
  	__free_pages_memory(start_pfn, end_pfn);
  
  	return end_pfn - start_pfn;
  }
  
  static unsigned long __init free_low_memory_core_early(void)
  {
  	unsigned long count = 0;
  	phys_addr_t start, end;
  	u64 i;
  
  	memblock_clear_hotplug(0, -1);
9f3d5eaa3   Mike Rapoport   memblock: impleme...
1895
  	for_each_reserved_mem_range(i, &start, &end)
bda49a811   Mike Rapoport   mm: remove nobootmem
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
  		reserve_bootmem_region(start, end);
  
  	/*
  	 * We need to use NUMA_NO_NODE instead of NODE_DATA(0)->node_id
  	 *  because in some case like Node0 doesn't have RAM installed
  	 *  low ram will be on Node1
  	 */
  	for_each_free_mem_range(i, NUMA_NO_NODE, MEMBLOCK_NONE, &start, &end,
  				NULL)
  		count += __free_memory_core(start, end);
  
  	return count;
  }
  
  static int reset_managed_pages_done __initdata;
  
  void reset_node_managed_pages(pg_data_t *pgdat)
  {
  	struct zone *z;
  
  	for (z = pgdat->node_zones; z < pgdat->node_zones + MAX_NR_ZONES; z++)
9705bea5f   Arun KS   mm: convert zone-...
1917
  		atomic_long_set(&z->managed_pages, 0);
bda49a811   Mike Rapoport   mm: remove nobootmem
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
  }
  
  void __init reset_all_zones_managed_pages(void)
  {
  	struct pglist_data *pgdat;
  
  	if (reset_managed_pages_done)
  		return;
  
  	for_each_online_pgdat(pgdat)
  		reset_node_managed_pages(pgdat);
  
  	reset_managed_pages_done = 1;
  }
  
  /**
   * memblock_free_all - release free pages to the buddy allocator
   *
   * Return: the number of pages actually released.
   */
  unsigned long __init memblock_free_all(void)
  {
  	unsigned long pages;
  
  	reset_all_zones_managed_pages();
  
  	pages = free_low_memory_core_early();
ca79b0c21   Arun KS   mm: convert total...
1945
  	totalram_pages_add(pages);
bda49a811   Mike Rapoport   mm: remove nobootmem
1946
1947
1948
  
  	return pages;
  }
350e88bad   Mike Rapoport   mm: memblock: mak...
1949
  #if defined(CONFIG_DEBUG_FS) && defined(CONFIG_ARCH_KEEP_MEMBLOCK)
6d03b885f   Benjamin Herrenschmidt   memblock: Add deb...
1950
1951
1952
1953
1954
1955
  
  static int memblock_debug_show(struct seq_file *m, void *private)
  {
  	struct memblock_type *type = m->private;
  	struct memblock_region *reg;
  	int i;
5d63f81c9   Miles Chen   mm/memblock.c: re...
1956
  	phys_addr_t end;
6d03b885f   Benjamin Herrenschmidt   memblock: Add deb...
1957
1958
1959
  
  	for (i = 0; i < type->cnt; i++) {
  		reg = &type->regions[i];
5d63f81c9   Miles Chen   mm/memblock.c: re...
1960
  		end = reg->base + reg->size - 1;
6d03b885f   Benjamin Herrenschmidt   memblock: Add deb...
1961

5d63f81c9   Miles Chen   mm/memblock.c: re...
1962
1963
1964
  		seq_printf(m, "%4d: ", i);
  		seq_printf(m, "%pa..%pa
  ", &reg->base, &end);
6d03b885f   Benjamin Herrenschmidt   memblock: Add deb...
1965
1966
1967
  	}
  	return 0;
  }
5ad350936   Andy Shevchenko   mm: reuse DEFINE_...
1968
  DEFINE_SHOW_ATTRIBUTE(memblock_debug);
6d03b885f   Benjamin Herrenschmidt   memblock: Add deb...
1969
1970
1971
1972
  
  static int __init memblock_init_debugfs(void)
  {
  	struct dentry *root = debugfs_create_dir("memblock", NULL);
d9f7979c9   Greg Kroah-Hartman   mm: no need to ch...
1973

0825a6f98   Joe Perches   mm: use octal not...
1974
1975
1976
1977
  	debugfs_create_file("memory", 0444, root,
  			    &memblock.memory, &memblock_debug_fops);
  	debugfs_create_file("reserved", 0444, root,
  			    &memblock.reserved, &memblock_debug_fops);
70210ed95   Philipp Hachtmann   mm/memblock: add ...
1978
  #ifdef CONFIG_HAVE_MEMBLOCK_PHYS_MAP
776499058   David Hildenbrand   mm/memblock: expo...
1979
1980
  	debugfs_create_file("physmem", 0444, root, &physmem,
  			    &memblock_debug_fops);
70210ed95   Philipp Hachtmann   mm/memblock: add ...
1981
  #endif
6d03b885f   Benjamin Herrenschmidt   memblock: Add deb...
1982
1983
1984
1985
1986
1987
  
  	return 0;
  }
  __initcall(memblock_init_debugfs);
  
  #endif /* CONFIG_DEBUG_FS */