16
16
#include <linux/kmemleak.h>
17
17
#include <linux/seq_file.h>
18
18
#include <linux/memblock.h>
19
+ #include <linux/mutex.h>
19
20
20
21
#include <asm/sections.h>
21
22
#include <linux/io.h>
@@ -2283,6 +2284,7 @@ struct reserve_mem_table {
2283
2284
};
2284
2285
static struct reserve_mem_table reserved_mem_table [RESERVE_MEM_MAX_ENTRIES ];
2285
2286
static int reserved_mem_count ;
2287
+ static DEFINE_MUTEX (reserve_mem_lock );
2286
2288
2287
2289
/* Add wildcard region with a lookup name */
2288
2290
static void __init reserved_mem_add (phys_addr_t start , phys_addr_t size ,
@@ -2296,6 +2298,21 @@ static void __init reserved_mem_add(phys_addr_t start, phys_addr_t size,
2296
2298
strscpy (map -> name , name );
2297
2299
}
2298
2300
2301
+ static struct reserve_mem_table * reserve_mem_find_by_name_nolock (const char * name )
2302
+ {
2303
+ struct reserve_mem_table * map ;
2304
+ int i ;
2305
+
2306
+ for (i = 0 ; i < reserved_mem_count ; i ++ ) {
2307
+ map = & reserved_mem_table [i ];
2308
+ if (!map -> size )
2309
+ continue ;
2310
+ if (strcmp (name , map -> name ) == 0 )
2311
+ return map ;
2312
+ }
2313
+ return NULL ;
2314
+ }
2315
+
2299
2316
/**
2300
2317
* reserve_mem_find_by_name - Find reserved memory region with a given name
2301
2318
* @name: The name that is attached to a reserved memory region
@@ -2309,22 +2326,47 @@ static void __init reserved_mem_add(phys_addr_t start, phys_addr_t size,
2309
2326
int reserve_mem_find_by_name (const char * name , phys_addr_t * start , phys_addr_t * size )
2310
2327
{
2311
2328
struct reserve_mem_table * map ;
2312
- int i ;
2313
2329
2314
- for (i = 0 ; i < reserved_mem_count ; i ++ ) {
2315
- map = & reserved_mem_table [i ];
2316
- if (!map -> size )
2317
- continue ;
2318
- if (strcmp (name , map -> name ) == 0 ) {
2319
- * start = map -> start ;
2320
- * size = map -> size ;
2321
- return 1 ;
2322
- }
2323
- }
2324
- return 0 ;
2330
+ guard (mutex )(& reserve_mem_lock );
2331
+ map = reserve_mem_find_by_name_nolock (name );
2332
+ if (!map )
2333
+ return 0 ;
2334
+
2335
+ * start = map -> start ;
2336
+ * size = map -> size ;
2337
+ return 1 ;
2325
2338
}
2326
2339
EXPORT_SYMBOL_GPL (reserve_mem_find_by_name );
2327
2340
2341
+ /**
2342
+ * reserve_mem_release_by_name - Release reserved memory region with a given name
2343
+ * @name: The name that is attatched to a reserved memory region
2344
+ *
2345
+ * Forcibly release the pages in the reserved memory region so that those memory
2346
+ * can be used as free memory. After released the reserved region size becomes 0.
2347
+ *
2348
+ * Returns: 1 if released or 0 if not found.
2349
+ */
2350
+ int reserve_mem_release_by_name (const char * name )
2351
+ {
2352
+ char buf [RESERVE_MEM_NAME_SIZE + 12 ];
2353
+ struct reserve_mem_table * map ;
2354
+ void * start , * end ;
2355
+
2356
+ guard (mutex )(& reserve_mem_lock );
2357
+ map = reserve_mem_find_by_name_nolock (name );
2358
+ if (!map )
2359
+ return 0 ;
2360
+
2361
+ start = phys_to_virt (map -> start );
2362
+ end = start + map -> size - 1 ;
2363
+ snprintf (buf , sizeof (buf ), "reserve_mem:%s" , name );
2364
+ free_reserved_area (start , end , 0 , buf );
2365
+ map -> size = 0 ;
2366
+
2367
+ return 1 ;
2368
+ }
2369
+
2328
2370
/*
2329
2371
* Parse reserve_mem=nn:align:name
2330
2372
*/
0 commit comments