Commit 77649905 authored by David Hildenbrand's avatar David Hildenbrand Committed by Heiko Carstens

mm/memblock: expose only miminal interface to add/walk physmem

"physmem" in the memblock allocator is somewhat weird: it's not actually
used for allocation, it's simply information collected during boot, which
describes the unmodified physical memory map at boot time, without any
standby/hotplugged memory. It's only used on s390 and is currently the
only reason s390 keeps using CONFIG_ARCH_KEEP_MEMBLOCK.

Physmem isn't numa aware and current users don't specify any flags. Let's
hide it from the user, exposing only for_each_physmem(), and simplify. The
interface for physmem is now really minimalistic:
- memblock_physmem_add() to add ranges
- for_each_physmem() / __next_physmem_range() to walk physmem ranges

Don't place it into an __init section and don't discard it without
CONFIG_ARCH_KEEP_MEMBLOCK. As we're reusing __next_mem_range(), remove
the __meminit notifier to avoid section mismatch warnings once
CONFIG_ARCH_KEEP_MEMBLOCK is no longer used with
CONFIG_HAVE_MEMBLOCK_PHYS_MAP.

While fixing up the documentation, sneak in some related cleanups. We can
stop setting CONFIG_ARCH_KEEP_MEMBLOCK for s390 next.

Cc: Vasily Gorbik <gor@linux.ibm.com>
Cc: Christian Borntraeger <borntraeger@de.ibm.com>
Cc: Mike Rapoport <rppt@linux.ibm.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarDavid Hildenbrand <david@redhat.com>
Reviewed-by: default avatarMike Rapoport <rppt@linux.ibm.com>
Message-Id: <20200701141830.18749-2-david@redhat.com>
Signed-off-by: default avatarHeiko Carstens <hca@linux.ibm.com>
parent a303e887
...@@ -549,8 +549,7 @@ static int get_mem_chunk_cnt(void) ...@@ -549,8 +549,7 @@ static int get_mem_chunk_cnt(void)
int cnt = 0; int cnt = 0;
u64 idx; u64 idx;
for_each_mem_range(idx, &memblock.physmem, &oldmem_type, NUMA_NO_NODE, for_each_physmem_range(idx, &oldmem_type, NULL, NULL)
MEMBLOCK_NONE, NULL, NULL, NULL)
cnt++; cnt++;
return cnt; return cnt;
} }
...@@ -563,8 +562,7 @@ static void loads_init(Elf64_Phdr *phdr, u64 loads_offset) ...@@ -563,8 +562,7 @@ static void loads_init(Elf64_Phdr *phdr, u64 loads_offset)
phys_addr_t start, end; phys_addr_t start, end;
u64 idx; u64 idx;
for_each_mem_range(idx, &memblock.physmem, &oldmem_type, NUMA_NO_NODE, for_each_physmem_range(idx, &oldmem_type, &start, &end) {
MEMBLOCK_NONE, &start, &end, NULL) {
phdr->p_filesz = end - start; phdr->p_filesz = end - start;
phdr->p_type = PT_LOAD; phdr->p_type = PT_LOAD;
phdr->p_offset = start; phdr->p_offset = start;
......
...@@ -77,16 +77,12 @@ struct memblock_type { ...@@ -77,16 +77,12 @@ struct memblock_type {
* @current_limit: physical address of the current allocation limit * @current_limit: physical address of the current allocation limit
* @memory: usable memory regions * @memory: usable memory regions
* @reserved: reserved memory regions * @reserved: reserved memory regions
* @physmem: all physical memory
*/ */
struct memblock { struct memblock {
bool bottom_up; /* is bottom up direction? */ bool bottom_up; /* is bottom up direction? */
phys_addr_t current_limit; phys_addr_t current_limit;
struct memblock_type memory; struct memblock_type memory;
struct memblock_type reserved; struct memblock_type reserved;
#ifdef CONFIG_HAVE_MEMBLOCK_PHYS_MAP
struct memblock_type physmem;
#endif
}; };
extern struct memblock memblock; extern struct memblock memblock;
...@@ -145,6 +141,30 @@ void __next_reserved_mem_region(u64 *idx, phys_addr_t *out_start, ...@@ -145,6 +141,30 @@ void __next_reserved_mem_region(u64 *idx, phys_addr_t *out_start,
void __memblock_free_late(phys_addr_t base, phys_addr_t size); void __memblock_free_late(phys_addr_t base, phys_addr_t size);
#ifdef CONFIG_HAVE_MEMBLOCK_PHYS_MAP
static inline void __next_physmem_range(u64 *idx, struct memblock_type *type,
phys_addr_t *out_start,
phys_addr_t *out_end)
{
extern struct memblock_type physmem;
__next_mem_range(idx, NUMA_NO_NODE, MEMBLOCK_NONE, &physmem, type,
out_start, out_end, NULL);
}
/**
* for_each_physmem_range - iterate through physmem areas not included in type.
* @i: u64 used as loop variable
* @type: ptr to memblock_type which excludes from the iteration, can be %NULL
* @p_start: ptr to phys_addr_t for start address of the range, can be %NULL
* @p_end: ptr to phys_addr_t for end address of the range, can be %NULL
*/
#define for_each_physmem_range(i, type, p_start, p_end) \
for (i = 0, __next_physmem_range(&i, type, p_start, p_end); \
i != (u64)ULLONG_MAX; \
__next_physmem_range(&i, type, p_start, p_end))
#endif /* CONFIG_HAVE_MEMBLOCK_PHYS_MAP */
/** /**
* for_each_mem_range - iterate through memblock areas from type_a and not * for_each_mem_range - iterate through memblock areas from type_a and not
* included in type_b. Or just type_a if type_b is NULL. * included in type_b. Or just type_a if type_b is NULL.
......
...@@ -44,19 +44,20 @@ ...@@ -44,19 +44,20 @@
* in the system, for instance when the memory is restricted with * in the system, for instance when the memory is restricted with
* ``mem=`` command line parameter * ``mem=`` command line parameter
* * ``reserved`` - describes the regions that were allocated * * ``reserved`` - describes the regions that were allocated
* * ``physmap`` - describes the actual physical memory regardless of * * ``physmem`` - describes the actual physical memory available during
* the possible restrictions; the ``physmap`` type is only available * boot regardless of the possible restrictions and memory hot(un)plug;
* on some architectures. * the ``physmem`` type is only available on some architectures.
* *
* Each region is represented by :c:type:`struct memblock_region` that * Each region is represented by :c:type:`struct memblock_region` that
* defines the region extents, its attributes and NUMA node id on NUMA * defines the region extents, its attributes and NUMA node id on NUMA
* systems. Every memory type is described by the :c:type:`struct * systems. Every memory type is described by the :c:type:`struct
* memblock_type` which contains an array of memory regions along with * memblock_type` which contains an array of memory regions along with
* the allocator metadata. The memory types are nicely wrapped with * the allocator metadata. The "memory" and "reserved" types are nicely
* :c:type:`struct memblock`. This structure is statically initialzed * wrapped with :c:type:`struct memblock`. This structure is statically
* at build time. The region arrays for the "memory" and "reserved" * initialized at build time. The region arrays are initially sized to
* types are initially sized to %INIT_MEMBLOCK_REGIONS and for the * %INIT_MEMBLOCK_REGIONS for "memory" and %INIT_MEMBLOCK_RESERVED_REGIONS
* "physmap" type to %INIT_PHYSMEM_REGIONS. * for "reserved". The region array for "physmem" is initially sized to
* %INIT_PHYSMEM_REGIONS.
* The memblock_allow_resize() enables automatic resizing of the region * The memblock_allow_resize() enables automatic resizing of the region
* arrays during addition of new regions. This feature should be used * arrays during addition of new regions. This feature should be used
* with care so that memory allocated for the region array will not * with care so that memory allocated for the region array will not
...@@ -87,8 +88,8 @@ ...@@ -87,8 +88,8 @@
* function frees all the memory to the buddy page allocator. * function frees all the memory to the buddy page allocator.
* *
* Unless an architecture enables %CONFIG_ARCH_KEEP_MEMBLOCK, the * Unless an architecture enables %CONFIG_ARCH_KEEP_MEMBLOCK, the
* memblock data structures will be discarded after the system * memblock data structures (except "physmem") will be discarded after the
* initialization completes. * system initialization completes.
*/ */
#ifndef CONFIG_NEED_MULTIPLE_NODES #ifndef CONFIG_NEED_MULTIPLE_NODES
...@@ -104,7 +105,7 @@ unsigned long long max_possible_pfn; ...@@ -104,7 +105,7 @@ unsigned long long max_possible_pfn;
static struct memblock_region memblock_memory_init_regions[INIT_MEMBLOCK_REGIONS] __initdata_memblock; static struct memblock_region memblock_memory_init_regions[INIT_MEMBLOCK_REGIONS] __initdata_memblock;
static struct memblock_region memblock_reserved_init_regions[INIT_MEMBLOCK_RESERVED_REGIONS] __initdata_memblock; static struct memblock_region memblock_reserved_init_regions[INIT_MEMBLOCK_RESERVED_REGIONS] __initdata_memblock;
#ifdef CONFIG_HAVE_MEMBLOCK_PHYS_MAP #ifdef CONFIG_HAVE_MEMBLOCK_PHYS_MAP
static struct memblock_region memblock_physmem_init_regions[INIT_PHYSMEM_REGIONS] __initdata_memblock; static struct memblock_region memblock_physmem_init_regions[INIT_PHYSMEM_REGIONS];
#endif #endif
struct memblock memblock __initdata_memblock = { struct memblock memblock __initdata_memblock = {
...@@ -118,17 +119,19 @@ struct memblock memblock __initdata_memblock = { ...@@ -118,17 +119,19 @@ struct memblock memblock __initdata_memblock = {
.reserved.max = INIT_MEMBLOCK_RESERVED_REGIONS, .reserved.max = INIT_MEMBLOCK_RESERVED_REGIONS,
.reserved.name = "reserved", .reserved.name = "reserved",
#ifdef CONFIG_HAVE_MEMBLOCK_PHYS_MAP
.physmem.regions = memblock_physmem_init_regions,
.physmem.cnt = 1, /* empty dummy entry */
.physmem.max = INIT_PHYSMEM_REGIONS,
.physmem.name = "physmem",
#endif
.bottom_up = false, .bottom_up = false,
.current_limit = MEMBLOCK_ALLOC_ANYWHERE, .current_limit = MEMBLOCK_ALLOC_ANYWHERE,
}; };
#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
int memblock_debug __initdata_memblock; int memblock_debug __initdata_memblock;
static bool system_has_some_mirror __initdata_memblock = false; static bool system_has_some_mirror __initdata_memblock = false;
static int memblock_can_resize __initdata_memblock; static int memblock_can_resize __initdata_memblock;
...@@ -838,7 +841,7 @@ int __init_memblock memblock_physmem_add(phys_addr_t base, phys_addr_t size) ...@@ -838,7 +841,7 @@ int __init_memblock memblock_physmem_add(phys_addr_t base, phys_addr_t size)
memblock_dbg("%s: [%pa-%pa] %pS\n", __func__, memblock_dbg("%s: [%pa-%pa] %pS\n", __func__,
&base, &end, (void *)_RET_IP_); &base, &end, (void *)_RET_IP_);
return memblock_add_range(&memblock.physmem, base, size, MAX_NUMNODES, 0); return memblock_add_range(&physmem, base, size, MAX_NUMNODES, 0);
} }
#endif #endif
...@@ -1019,12 +1022,10 @@ static bool should_skip_region(struct memblock_region *m, int nid, int flags) ...@@ -1019,12 +1022,10 @@ static bool should_skip_region(struct memblock_region *m, int nid, int flags)
* As both region arrays are sorted, the function advances the two indices * As both region arrays are sorted, the function advances the two indices
* in lockstep and returns each intersection. * in lockstep and returns each intersection.
*/ */
void __init_memblock __next_mem_range(u64 *idx, int nid, void __next_mem_range(u64 *idx, int nid, enum memblock_flags flags,
enum memblock_flags flags, struct memblock_type *type_a,
struct memblock_type *type_a, struct memblock_type *type_b, phys_addr_t *out_start,
struct memblock_type *type_b, phys_addr_t *out_end, int *out_nid)
phys_addr_t *out_start,
phys_addr_t *out_end, int *out_nid)
{ {
int idx_a = *idx & 0xffffffff; int idx_a = *idx & 0xffffffff;
int idx_b = *idx >> 32; int idx_b = *idx >> 32;
...@@ -1924,7 +1925,7 @@ void __init_memblock __memblock_dump_all(void) ...@@ -1924,7 +1925,7 @@ void __init_memblock __memblock_dump_all(void)
memblock_dump(&memblock.memory); memblock_dump(&memblock.memory);
memblock_dump(&memblock.reserved); memblock_dump(&memblock.reserved);
#ifdef CONFIG_HAVE_MEMBLOCK_PHYS_MAP #ifdef CONFIG_HAVE_MEMBLOCK_PHYS_MAP
memblock_dump(&memblock.physmem); memblock_dump(&physmem);
#endif #endif
} }
...@@ -2064,8 +2065,8 @@ static int __init memblock_init_debugfs(void) ...@@ -2064,8 +2065,8 @@ static int __init memblock_init_debugfs(void)
debugfs_create_file("reserved", 0444, root, debugfs_create_file("reserved", 0444, root,
&memblock.reserved, &memblock_debug_fops); &memblock.reserved, &memblock_debug_fops);
#ifdef CONFIG_HAVE_MEMBLOCK_PHYS_MAP #ifdef CONFIG_HAVE_MEMBLOCK_PHYS_MAP
debugfs_create_file("physmem", 0444, root, debugfs_create_file("physmem", 0444, root, &physmem,
&memblock.physmem, &memblock_debug_fops); &memblock_debug_fops);
#endif #endif
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment