]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
s390/boot: Add physmem tracking debug support
authorVasily Gorbik <gor@linux.ibm.com>
Wed, 11 Dec 2024 10:06:19 +0000 (11:06 +0100)
committerAlexander Gordeev <agordeev@linux.ibm.com>
Sun, 26 Jan 2025 16:24:02 +0000 (17:24 +0100)
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>
arch/s390/boot/boot.h
arch/s390/boot/physmem_info.c
arch/s390/boot/startup.c
arch/s390/include/asm/physmem_info.h
arch/s390/kernel/setup.c

index 0cfa84a42ec17e5054dfb1564816da9cfacd4589..69f261566a64a8b78c447c0673aa83df3ad176d5 100644 (file)
@@ -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);
index 37d201986261c5058314fbe661ce49bf101c894a..aa096ef68e8c217e829ad89ced31fcb425b15940 100644 (file)
@@ -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);
+               }
+       }
+}
index e9ae589c616944c61e276c1839bbc51ecccd404e..86693d838e9742305616402badd4a079e812ab47 100644 (file)
@@ -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,
index 51b68a43e19577f3d9fd832ab1f82482f34ebb4e..7ef3bbec98b080bd23c4c4d8f8382f55c501654d 100644 (file)
@@ -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";
index 20fc68bdefa13336cebfbf416dbec4b120984936..0fcb2a4e3f5ee095a1f8aaf85c78bf2512fca760 100644 (file)
@@ -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);
 }