s390/boot: Add physmem tracking debug support
Introduce boot_debug() calls to track memory detection, online ranges, reserved areas, and allocations (except for VMEM allocations, which are too frequent). Instead introduce dump_physmem_reserved() function which prints out full memory tracking information. This helps in debugging early boot memory handling. Signed-off-by: Vasily Gorbik <gor@linux.ibm.com> Acked-by: Heiko Carstens <hca@linux.ibm.com> Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
This commit is contained in:
committed by
Alexander Gordeev
parent
d2ebe06bf5
commit
9688b17b4a
@@ -57,6 +57,7 @@ unsigned long physmem_alloc_range(enum reserved_range_type type, unsigned long s
|
||||
unsigned long align, unsigned long min, unsigned long max,
|
||||
bool die_on_oom);
|
||||
unsigned long get_physmem_alloc_pos(void);
|
||||
void dump_physmem_reserved(void);
|
||||
bool ipl_report_certs_intersects(unsigned long addr, unsigned long size,
|
||||
unsigned long *intersection_start);
|
||||
bool is_ipl_block_dump(void);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
#define boot_fmt(fmt) "physmem: " fmt
|
||||
#include <linux/processor.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/init.h>
|
||||
@@ -28,7 +29,7 @@ static struct physmem_range *__get_physmem_range_ptr(u32 n)
|
||||
return &physmem_info.online[n];
|
||||
if (unlikely(!physmem_info.online_extended)) {
|
||||
physmem_info.online_extended = (struct physmem_range *)physmem_alloc_range(
|
||||
RR_MEM_DETECT_EXTENDED, ENTRIES_EXTENDED_MAX, sizeof(long), 0,
|
||||
RR_MEM_DETECT_EXT, ENTRIES_EXTENDED_MAX, sizeof(long), 0,
|
||||
physmem_alloc_pos, true);
|
||||
}
|
||||
return &physmem_info.online_extended[n - MEM_INLINED_ENTRIES];
|
||||
@@ -207,11 +208,16 @@ unsigned long detect_max_physmem_end(void)
|
||||
max_physmem_end = search_mem_end();
|
||||
physmem_info.info_source = MEM_DETECT_BIN_SEARCH;
|
||||
}
|
||||
boot_debug("Max physical memory: 0x%016lx (info source: %s)\n", max_physmem_end,
|
||||
get_physmem_info_source());
|
||||
return max_physmem_end;
|
||||
}
|
||||
|
||||
void detect_physmem_online_ranges(unsigned long max_physmem_end)
|
||||
{
|
||||
unsigned long start, end;
|
||||
int i;
|
||||
|
||||
if (!sclp_early_read_storage_info()) {
|
||||
physmem_info.info_source = MEM_DETECT_SCLP_STOR_INFO;
|
||||
} else if (physmem_info.info_source == MEM_DETECT_DIAG500_STOR_LIMIT) {
|
||||
@@ -226,12 +232,16 @@ void detect_physmem_online_ranges(unsigned long max_physmem_end)
|
||||
} else if (max_physmem_end) {
|
||||
add_physmem_online_range(0, max_physmem_end);
|
||||
}
|
||||
boot_debug("Online memory ranges (info source: %s):\n", get_physmem_info_source());
|
||||
for_each_physmem_online_range(i, &start, &end)
|
||||
boot_debug(" online [%d]: 0x%016lx-0x%016lx\n", i, start, end);
|
||||
}
|
||||
|
||||
void physmem_set_usable_limit(unsigned long limit)
|
||||
{
|
||||
physmem_info.usable = limit;
|
||||
physmem_alloc_pos = limit;
|
||||
boot_debug("Usable memory limit: 0x%016lx\n", limit);
|
||||
}
|
||||
|
||||
static void die_oom(unsigned long size, unsigned long align, unsigned long min, unsigned long max)
|
||||
@@ -265,14 +275,23 @@ static void die_oom(unsigned long size, unsigned long align, unsigned long min,
|
||||
disabled_wait();
|
||||
}
|
||||
|
||||
void physmem_reserve(enum reserved_range_type type, unsigned long addr, unsigned long size)
|
||||
static void _physmem_reserve(enum reserved_range_type type, unsigned long addr, unsigned long size)
|
||||
{
|
||||
physmem_info.reserved[type].start = addr;
|
||||
physmem_info.reserved[type].end = addr + size;
|
||||
}
|
||||
|
||||
void physmem_reserve(enum reserved_range_type type, unsigned long addr, unsigned long size)
|
||||
{
|
||||
_physmem_reserve(type, addr, size);
|
||||
boot_debug("%-14s 0x%016lx-0x%016lx %s\n", "Reserve:", addr, addr + size,
|
||||
get_rr_type_name(type));
|
||||
}
|
||||
|
||||
void physmem_free(enum reserved_range_type type)
|
||||
{
|
||||
boot_debug("%-14s 0x%016lx-0x%016lx %s\n", "Free:", physmem_info.reserved[type].start,
|
||||
physmem_info.reserved[type].end, get_rr_type_name(type));
|
||||
physmem_info.reserved[type].start = 0;
|
||||
physmem_info.reserved[type].end = 0;
|
||||
}
|
||||
@@ -339,7 +358,9 @@ unsigned long physmem_alloc_range(enum reserved_range_type type, unsigned long s
|
||||
max = min(max, physmem_alloc_pos);
|
||||
addr = __physmem_alloc_range(size, align, min, max, 0, NULL, die_on_oom);
|
||||
if (addr)
|
||||
physmem_reserve(type, addr, size);
|
||||
_physmem_reserve(type, addr, size);
|
||||
boot_debug("%-14s 0x%016lx-0x%016lx %s\n", "Alloc range:", addr, addr + size,
|
||||
get_rr_type_name(type));
|
||||
return addr;
|
||||
}
|
||||
|
||||
@@ -347,7 +368,7 @@ unsigned long physmem_alloc(enum reserved_range_type type, unsigned long size,
|
||||
unsigned long align, bool die_on_oom)
|
||||
{
|
||||
struct reserved_range *range = &physmem_info.reserved[type];
|
||||
struct reserved_range *new_range;
|
||||
struct reserved_range *new_range = NULL;
|
||||
unsigned int ranges_left;
|
||||
unsigned long addr;
|
||||
|
||||
@@ -371,6 +392,10 @@ unsigned long physmem_alloc(enum reserved_range_type type, unsigned long size,
|
||||
}
|
||||
range->end = addr + size;
|
||||
}
|
||||
if (type != RR_VMEM) {
|
||||
boot_debug("%-14s 0x%016lx-0x%016lx %-20s align 0x%lx split %d\n", "Alloc topdown:",
|
||||
addr, addr + size, get_rr_type_name(type), align, !!new_range);
|
||||
}
|
||||
range->start = addr;
|
||||
physmem_alloc_pos = addr;
|
||||
physmem_alloc_ranges = ranges_left;
|
||||
@@ -387,3 +412,19 @@ unsigned long get_physmem_alloc_pos(void)
|
||||
{
|
||||
return physmem_alloc_pos;
|
||||
}
|
||||
|
||||
void dump_physmem_reserved(void)
|
||||
{
|
||||
struct reserved_range *range;
|
||||
enum reserved_range_type t;
|
||||
unsigned long start, end;
|
||||
|
||||
boot_debug("Reserved memory ranges:\n");
|
||||
for_each_physmem_reserved_range(t, range, &start, &end) {
|
||||
if (end) {
|
||||
boot_debug("%-14s 0x%016lx-0x%016lx @%012lx chain %012lx\n",
|
||||
get_rr_type_name(t), start, end, (unsigned long)range,
|
||||
(unsigned long)range->chain);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -525,6 +525,7 @@ void startup_kernel(void)
|
||||
__kaslr_offset, __kaslr_offset_phys);
|
||||
kaslr_adjust_got(__kaslr_offset);
|
||||
setup_vmem(__kaslr_offset, __kaslr_offset + kernel_size, asce_limit);
|
||||
dump_physmem_reserved();
|
||||
copy_bootdata();
|
||||
__apply_alternatives((struct alt_instr *)_vmlinux_info.alt_instructions,
|
||||
(struct alt_instr *)_vmlinux_info.alt_instructions_end,
|
||||
|
||||
@@ -26,7 +26,7 @@ enum reserved_range_type {
|
||||
RR_AMODE31,
|
||||
RR_IPLREPORT,
|
||||
RR_CERT_COMP_LIST,
|
||||
RR_MEM_DETECT_EXTENDED,
|
||||
RR_MEM_DETECT_EXT,
|
||||
RR_VMEM,
|
||||
RR_MAX
|
||||
};
|
||||
@@ -128,7 +128,7 @@ static inline const char *get_rr_type_name(enum reserved_range_type t)
|
||||
RR_TYPE_NAME(AMODE31);
|
||||
RR_TYPE_NAME(IPLREPORT);
|
||||
RR_TYPE_NAME(CERT_COMP_LIST);
|
||||
RR_TYPE_NAME(MEM_DETECT_EXTENDED);
|
||||
RR_TYPE_NAME(MEM_DETECT_EXT);
|
||||
RR_TYPE_NAME(VMEM);
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
|
||||
@@ -702,7 +702,7 @@ static void __init reserve_physmem_info(void)
|
||||
{
|
||||
unsigned long addr, size;
|
||||
|
||||
if (get_physmem_reserved(RR_MEM_DETECT_EXTENDED, &addr, &size))
|
||||
if (get_physmem_reserved(RR_MEM_DETECT_EXT, &addr, &size))
|
||||
memblock_reserve(addr, size);
|
||||
}
|
||||
|
||||
@@ -710,7 +710,7 @@ static void __init free_physmem_info(void)
|
||||
{
|
||||
unsigned long addr, size;
|
||||
|
||||
if (get_physmem_reserved(RR_MEM_DETECT_EXTENDED, &addr, &size))
|
||||
if (get_physmem_reserved(RR_MEM_DETECT_EXT, &addr, &size))
|
||||
memblock_phys_free(addr, size);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user