Skip to content

Commit 8512530

Browse files
author
AKASHI Takahiro
committed
memblock: add memblock_cap_memory_range()
Add memblock_cap_memory_range() which will remove all the memblock regions except the memory range specified in the arguments. In addition, rework is done on memblock_mem_limit_remove_map() to re-implement it using memblock_cap_memory_range(). This function, like memblock_mem_limit_remove_map(), will not remove memblocks with MEMMAP_NOMAP attribute as they may be mapped and accessed later as "device memory." See the commit a571d4eb55d8 ("mm/memblock.c: add new infrastructure to address the mem limit issue"). This function is used, in a succeeding patch in the series of arm64 kdump suuport, to limit the range of usable memory, or System RAM, on crash dump kernel. (Please note that "mem=" parameter is of little use for this purpose.) Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org> Reviewed-by: Will Deacon <will.deacon@arm.com> Acked-by: Catalin Marinas <catalin.marinas@arm.com> Acked-by: Dennis Chen <dennis.chen@arm.com> Cc: linux-mm@kvack.org Cc: Andrew Morton <akpm@linux-foundation.org> Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
1 parent fc7b7e9 commit 8512530

2 files changed

Lines changed: 30 additions & 15 deletions

File tree

include/linux/memblock.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,7 @@ phys_addr_t memblock_mem_size(unsigned long limit_pfn);
326326
phys_addr_t memblock_start_of_DRAM(void);
327327
phys_addr_t memblock_end_of_DRAM(void);
328328
void memblock_enforce_memory_limit(phys_addr_t memory_limit);
329+
void memblock_cap_memory_range(phys_addr_t base, phys_addr_t size);
329330
void memblock_mem_limit_remove_map(phys_addr_t limit);
330331
bool memblock_is_memory(phys_addr_t addr);
331332
int memblock_is_map_memory(phys_addr_t addr);

mm/memblock.c

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1539,11 +1539,37 @@ void __init memblock_enforce_memory_limit(phys_addr_t limit)
15391539
(phys_addr_t)ULLONG_MAX);
15401540
}
15411541

1542+
void __init memblock_cap_memory_range(phys_addr_t base, phys_addr_t size)
1543+
{
1544+
int start_rgn, end_rgn;
1545+
int i, ret;
1546+
1547+
if (!size)
1548+
return;
1549+
1550+
ret = memblock_isolate_range(&memblock.memory, base, size,
1551+
&start_rgn, &end_rgn);
1552+
if (ret)
1553+
return;
1554+
1555+
/* remove all the MAP regions */
1556+
for (i = memblock.memory.cnt - 1; i >= end_rgn; i--)
1557+
if (!memblock_is_nomap(&memblock.memory.regions[i]))
1558+
memblock_remove_region(&memblock.memory, i);
1559+
1560+
for (i = start_rgn - 1; i >= 0; i--)
1561+
if (!memblock_is_nomap(&memblock.memory.regions[i]))
1562+
memblock_remove_region(&memblock.memory, i);
1563+
1564+
/* truncate the reserved regions */
1565+
memblock_remove_range(&memblock.reserved, 0, base);
1566+
memblock_remove_range(&memblock.reserved,
1567+
base + size, (phys_addr_t)ULLONG_MAX);
1568+
}
1569+
15421570
void __init memblock_mem_limit_remove_map(phys_addr_t limit)
15431571
{
1544-
struct memblock_type *type = &memblock.memory;
15451572
phys_addr_t max_addr;
1546-
int i, ret, start_rgn, end_rgn;
15471573

15481574
if (!limit)
15491575
return;
@@ -1554,19 +1580,7 @@ void __init memblock_mem_limit_remove_map(phys_addr_t limit)
15541580
if (max_addr == (phys_addr_t)ULLONG_MAX)
15551581
return;
15561582

1557-
ret = memblock_isolate_range(type, max_addr, (phys_addr_t)ULLONG_MAX,
1558-
&start_rgn, &end_rgn);
1559-
if (ret)
1560-
return;
1561-
1562-
/* remove all the MAP regions above the limit */
1563-
for (i = end_rgn - 1; i >= start_rgn; i--) {
1564-
if (!memblock_is_nomap(&type->regions[i]))
1565-
memblock_remove_region(type, i);
1566-
}
1567-
/* truncate the reserved regions */
1568-
memblock_remove_range(&memblock.reserved, max_addr,
1569-
(phys_addr_t)ULLONG_MAX);
1583+
memblock_cap_memory_range(0, max_addr);
15701584
}
15711585

15721586
static int __init_memblock memblock_search(struct memblock_type *type, phys_addr_t addr)

0 commit comments

Comments
 (0)