Skip to content

Commit 74e2498

Browse files
mhiramatrostedt
authored andcommitted
mm/memblock: Add reserved memory release function
Add reserve_mem_release_by_name() to release a reserved memory region with a given name. This allows us to release reserved memory which is defined by kernel cmdline, after boot. Signed-off-by: Masami Hiramatsu (Google) <[email protected]> Acked-by: Mike Rapoport (Microsoft) <[email protected]> Cc: Andrew Morton <[email protected]> Cc: Mark Rutland <[email protected]> Cc: Mathieu Desnoyers <[email protected]> Cc: [email protected] Link: https://lore.kernel.org/173989133862.230693.14094993331347437600.stgit@devnote2 Signed-off-by: Steven Rostedt (Google) <[email protected]>
1 parent 5f3719f commit 74e2498

File tree

2 files changed

+55
-12
lines changed

2 files changed

+55
-12
lines changed

include/linux/mm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4123,6 +4123,7 @@ void vma_pgtable_walk_begin(struct vm_area_struct *vma);
41234123
void vma_pgtable_walk_end(struct vm_area_struct *vma);
41244124

41254125
int reserve_mem_find_by_name(const char *name, phys_addr_t *start, phys_addr_t *size);
4126+
int reserve_mem_release_by_name(const char *name);
41264127

41274128
#ifdef CONFIG_64BIT
41284129
int do_mseal(unsigned long start, size_t len_in, unsigned long flags);

mm/memblock.c

Lines changed: 54 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <linux/kmemleak.h>
1717
#include <linux/seq_file.h>
1818
#include <linux/memblock.h>
19+
#include <linux/mutex.h>
1920

2021
#include <asm/sections.h>
2122
#include <linux/io.h>
@@ -2283,6 +2284,7 @@ struct reserve_mem_table {
22832284
};
22842285
static struct reserve_mem_table reserved_mem_table[RESERVE_MEM_MAX_ENTRIES];
22852286
static int reserved_mem_count;
2287+
static DEFINE_MUTEX(reserve_mem_lock);
22862288

22872289
/* Add wildcard region with a lookup name */
22882290
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,
22962298
strscpy(map->name, name);
22972299
}
22982300

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+
22992316
/**
23002317
* reserve_mem_find_by_name - Find reserved memory region with a given name
23012318
* @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,
23092326
int reserve_mem_find_by_name(const char *name, phys_addr_t *start, phys_addr_t *size)
23102327
{
23112328
struct reserve_mem_table *map;
2312-
int i;
23132329

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;
23252338
}
23262339
EXPORT_SYMBOL_GPL(reserve_mem_find_by_name);
23272340

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+
23282370
/*
23292371
* Parse reserve_mem=nn:align:name
23302372
*/

0 commit comments

Comments
 (0)