@@ -114,12 +114,10 @@ static struct memblock_region memblock_physmem_init_regions[INIT_PHYSMEM_REGIONS
114
114
115
115
struct memblock memblock __initdata_memblock = {
116
116
.memory .regions = memblock_memory_init_regions ,
117
- .memory .cnt = 1 , /* empty dummy entry */
118
117
.memory .max = INIT_MEMBLOCK_MEMORY_REGIONS ,
119
118
.memory .name = "memory" ,
120
119
121
120
.reserved .regions = memblock_reserved_init_regions ,
122
- .reserved .cnt = 1 , /* empty dummy entry */
123
121
.reserved .max = INIT_MEMBLOCK_RESERVED_REGIONS ,
124
122
.reserved .name = "reserved" ,
125
123
@@ -130,7 +128,6 @@ struct memblock memblock __initdata_memblock = {
130
128
#ifdef CONFIG_HAVE_MEMBLOCK_PHYS_MAP
131
129
struct memblock_type physmem = {
132
130
.regions = memblock_physmem_init_regions ,
133
- .cnt = 1 , /* empty dummy entry */
134
131
.max = INIT_PHYSMEM_REGIONS ,
135
132
.name = "physmem" ,
136
133
};
@@ -197,8 +194,8 @@ bool __init_memblock memblock_overlaps_region(struct memblock_type *type,
197
194
for (i = 0 ; i < type -> cnt ; i ++ )
198
195
if (memblock_addrs_overlap (base , size , type -> regions [i ].base ,
199
196
type -> regions [i ].size ))
200
- break ;
201
- return i < type -> cnt ;
197
+ return true ;
198
+ return false ;
202
199
}
203
200
204
201
/**
@@ -356,7 +353,6 @@ static void __init_memblock memblock_remove_region(struct memblock_type *type, u
356
353
/* Special case for empty arrays */
357
354
if (type -> cnt == 0 ) {
358
355
WARN_ON (type -> total_size != 0 );
359
- type -> cnt = 1 ;
360
356
type -> regions [0 ].base = 0 ;
361
357
type -> regions [0 ].size = 0 ;
362
358
type -> regions [0 ].flags = 0 ;
@@ -600,12 +596,13 @@ static int __init_memblock memblock_add_range(struct memblock_type *type,
600
596
601
597
/* special case for empty array */
602
598
if (type -> regions [0 ].size == 0 ) {
603
- WARN_ON (type -> cnt != 1 || type -> total_size );
599
+ WARN_ON (type -> cnt != 0 || type -> total_size );
604
600
type -> regions [0 ].base = base ;
605
601
type -> regions [0 ].size = size ;
606
602
type -> regions [0 ].flags = flags ;
607
603
memblock_set_region_node (& type -> regions [0 ], nid );
608
604
type -> total_size = size ;
605
+ type -> cnt = 1 ;
609
606
return 0 ;
610
607
}
611
608
@@ -780,7 +777,8 @@ bool __init_memblock memblock_validate_numa_coverage(unsigned long threshold_byt
780
777
* Walk @type and ensure that regions don't cross the boundaries defined by
781
778
* [@base, @base + @size). Crossing regions are split at the boundaries,
782
779
* which may create at most two more regions. The index of the first
783
- * region inside the range is returned in *@start_rgn and end in *@end_rgn.
780
+ * region inside the range is returned in *@start_rgn and the index of the
781
+ * first region after the range is returned in *@end_rgn.
784
782
*
785
783
* Return:
786
784
* 0 on success, -errno on failure.
@@ -1441,6 +1439,17 @@ phys_addr_t __init memblock_alloc_range_nid(phys_addr_t size,
1441
1439
enum memblock_flags flags = choose_memblock_flags ();
1442
1440
phys_addr_t found ;
1443
1441
1442
+ /*
1443
+ * Detect any accidental use of these APIs after slab is ready, as at
1444
+ * this moment memblock may be deinitialized already and its
1445
+ * internal data may be destroyed (after execution of memblock_free_all)
1446
+ */
1447
+ if (WARN_ON_ONCE (slab_is_available ())) {
1448
+ void * vaddr = kzalloc_node (size , GFP_NOWAIT , nid );
1449
+
1450
+ return vaddr ? virt_to_phys (vaddr ) : 0 ;
1451
+ }
1452
+
1444
1453
if (!align ) {
1445
1454
/* Can't use WARNs this early in boot on powerpc */
1446
1455
dump_stack ();
@@ -1566,13 +1575,6 @@ static void * __init memblock_alloc_internal(
1566
1575
{
1567
1576
phys_addr_t alloc ;
1568
1577
1569
- /*
1570
- * Detect any accidental use of these APIs after slab is ready, as at
1571
- * this moment memblock may be deinitialized already and its
1572
- * internal data may be destroyed (after execution of memblock_free_all)
1573
- */
1574
- if (WARN_ON_ONCE (slab_is_available ()))
1575
- return kzalloc_node (size , GFP_NOWAIT , nid );
1576
1578
1577
1579
if (max_addr > memblock .current_limit )
1578
1580
max_addr = memblock .current_limit ;
@@ -2031,7 +2033,7 @@ static void __init free_memmap(unsigned long start_pfn, unsigned long end_pfn)
2031
2033
* downwards.
2032
2034
*/
2033
2035
pg = PAGE_ALIGN (__pa (start_pg ));
2034
- pgend = __pa (end_pg ) & PAGE_MASK ;
2036
+ pgend = PAGE_ALIGN_DOWN ( __pa (end_pg )) ;
2035
2037
2036
2038
/*
2037
2039
* If there are free pages between these, free the section of the
@@ -2234,6 +2236,123 @@ void __init memblock_free_all(void)
2234
2236
totalram_pages_add (pages );
2235
2237
}
2236
2238
2239
+ /* Keep a table to reserve named memory */
2240
+ #define RESERVE_MEM_MAX_ENTRIES 8
2241
+ #define RESERVE_MEM_NAME_SIZE 16
2242
+ struct reserve_mem_table {
2243
+ char name [RESERVE_MEM_NAME_SIZE ];
2244
+ phys_addr_t start ;
2245
+ phys_addr_t size ;
2246
+ };
2247
+ static struct reserve_mem_table reserved_mem_table [RESERVE_MEM_MAX_ENTRIES ];
2248
+ static int reserved_mem_count ;
2249
+
2250
+ /* Add wildcard region with a lookup name */
2251
+ static void __init reserved_mem_add (phys_addr_t start , phys_addr_t size ,
2252
+ const char * name )
2253
+ {
2254
+ struct reserve_mem_table * map ;
2255
+
2256
+ map = & reserved_mem_table [reserved_mem_count ++ ];
2257
+ map -> start = start ;
2258
+ map -> size = size ;
2259
+ strscpy (map -> name , name );
2260
+ }
2261
+
2262
+ /**
2263
+ * reserve_mem_find_by_name - Find reserved memory region with a given name
2264
+ * @name: The name that is attached to a reserved memory region
2265
+ * @start: If found, holds the start address
2266
+ * @size: If found, holds the size of the address.
2267
+ *
2268
+ * @start and @size are only updated if @name is found.
2269
+ *
2270
+ * Returns: 1 if found or 0 if not found.
2271
+ */
2272
+ int reserve_mem_find_by_name (const char * name , phys_addr_t * start , phys_addr_t * size )
2273
+ {
2274
+ struct reserve_mem_table * map ;
2275
+ int i ;
2276
+
2277
+ for (i = 0 ; i < reserved_mem_count ; i ++ ) {
2278
+ map = & reserved_mem_table [i ];
2279
+ if (!map -> size )
2280
+ continue ;
2281
+ if (strcmp (name , map -> name ) == 0 ) {
2282
+ * start = map -> start ;
2283
+ * size = map -> size ;
2284
+ return 1 ;
2285
+ }
2286
+ }
2287
+ return 0 ;
2288
+ }
2289
+ EXPORT_SYMBOL_GPL (reserve_mem_find_by_name );
2290
+
2291
+ /*
2292
+ * Parse reserve_mem=nn:align:name
2293
+ */
2294
+ static int __init reserve_mem (char * p )
2295
+ {
2296
+ phys_addr_t start , size , align , tmp ;
2297
+ char * name ;
2298
+ char * oldp ;
2299
+ int len ;
2300
+
2301
+ if (!p )
2302
+ return - EINVAL ;
2303
+
2304
+ /* Check if there's room for more reserved memory */
2305
+ if (reserved_mem_count >= RESERVE_MEM_MAX_ENTRIES )
2306
+ return - EBUSY ;
2307
+
2308
+ oldp = p ;
2309
+ size = memparse (p , & p );
2310
+ if (!size || p == oldp )
2311
+ return - EINVAL ;
2312
+
2313
+ if (* p != ':' )
2314
+ return - EINVAL ;
2315
+
2316
+ align = memparse (p + 1 , & p );
2317
+ if (* p != ':' )
2318
+ return - EINVAL ;
2319
+
2320
+ /*
2321
+ * memblock_phys_alloc() doesn't like a zero size align,
2322
+ * but it is OK for this command to have it.
2323
+ */
2324
+ if (align < SMP_CACHE_BYTES )
2325
+ align = SMP_CACHE_BYTES ;
2326
+
2327
+ name = p + 1 ;
2328
+ len = strlen (name );
2329
+
2330
+ /* name needs to have length but not too big */
2331
+ if (!len || len >= RESERVE_MEM_NAME_SIZE )
2332
+ return - EINVAL ;
2333
+
2334
+ /* Make sure that name has text */
2335
+ for (p = name ; * p ; p ++ ) {
2336
+ if (!isspace (* p ))
2337
+ break ;
2338
+ }
2339
+ if (!* p )
2340
+ return - EINVAL ;
2341
+
2342
+ /* Make sure the name is not already used */
2343
+ if (reserve_mem_find_by_name (name , & start , & tmp ))
2344
+ return - EBUSY ;
2345
+
2346
+ start = memblock_phys_alloc (size , align );
2347
+ if (!start )
2348
+ return - ENOMEM ;
2349
+
2350
+ reserved_mem_add (start , size , name );
2351
+
2352
+ return 1 ;
2353
+ }
2354
+ __setup ("reserve_mem=" , reserve_mem );
2355
+
2237
2356
#if defined(CONFIG_DEBUG_FS ) && defined(CONFIG_ARCH_KEEP_MEMBLOCK )
2238
2357
static const char * const flagname [] = {
2239
2358
[ilog2 (MEMBLOCK_HOTPLUG )] = "HOTPLUG" ,
0 commit comments