Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

memblock: Add reserve_mem debugfs info

When using the "reserve_mem" parameter, users aim at having an
area that (hopefully) persists across boots, so pstore infrastructure
(like ramoops module) can make use of that to save oops/ftrace logs,
for example.

There is no easy way to determine if this kernel parameter is properly
set though; the kernel doesn't show information about this memory in
memblock debugfs, neither in /proc/iomem nor dmesg. This is a relevant
information for tools like kdumpst[0], to determine if it's reliable
to use the reserved area as ramoops persistent storage; checking only
/proc/cmdline is not sufficient as it doesn't tell if the reservation
effectively succeeded or not.

Add here a new file under memblock debugfs showing properly set memory
reservations, with name and size as passed to "reserve_mem". Notice that
if no "reserve_mem=" is passed on command-line or if the reservation
attempts fail, the file is not created.

[0] https://aur.archlinux.org/packages/kdumpst

Reviewed-by: SeongJae Park <sj@kernel.org>
Signed-off-by: Guilherme G. Piccoli <gpiccoli@igalia.com>
Link: https://patch.msgid.link/20260324012839.1991765-2-gpiccoli@igalia.com
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>

authored by

Guilherme G. Piccoli and committed by
Mike Rapoport (Microsoft)
0709682c f7f4a21c

+55 -4
+45 -4
mm/memblock.c
··· 17 17 #include <linux/seq_file.h> 18 18 #include <linux/memblock.h> 19 19 #include <linux/mutex.h> 20 + #include <linux/string_helpers.h> 20 21 21 22 #ifdef CONFIG_KEXEC_HANDOVER 22 23 #include <linux/libfdt.h> ··· 2711 2710 } 2712 2711 __setup("reserve_mem=", reserve_mem); 2713 2712 2714 - #if defined(CONFIG_DEBUG_FS) && defined(CONFIG_ARCH_KEEP_MEMBLOCK) 2713 + #ifdef CONFIG_DEBUG_FS 2714 + #ifdef CONFIG_ARCH_KEEP_MEMBLOCK 2715 2715 static const char * const flagname[] = { 2716 2716 [ilog2(MEMBLOCK_HOTPLUG)] = "HOTPLUG", 2717 2717 [ilog2(MEMBLOCK_MIRROR)] = "MIRROR", ··· 2759 2757 } 2760 2758 DEFINE_SHOW_ATTRIBUTE(memblock_debug); 2761 2759 2762 - static int __init memblock_init_debugfs(void) 2760 + static inline void memblock_debugfs_expose_arrays(struct dentry *root) 2763 2761 { 2764 - struct dentry *root = debugfs_create_dir("memblock", NULL); 2765 - 2766 2762 debugfs_create_file("memory", 0444, root, 2767 2763 &memblock.memory, &memblock_debug_fops); 2768 2764 debugfs_create_file("reserved", 0444, root, ··· 2769 2769 debugfs_create_file("physmem", 0444, root, &physmem, 2770 2770 &memblock_debug_fops); 2771 2771 #endif 2772 + } 2772 2773 2774 + #else 2775 + 2776 + static inline void memblock_debugfs_expose_arrays(struct dentry *root) { } 2777 + 2778 + #endif /* CONFIG_ARCH_KEEP_MEMBLOCK */ 2779 + 2780 + static int memblock_reserve_mem_show(struct seq_file *m, void *private) 2781 + { 2782 + struct reserve_mem_table *map; 2783 + char txtsz[16]; 2784 + 2785 + guard(mutex)(&reserve_mem_lock); 2786 + for (int i = 0; i < reserved_mem_count; i++) { 2787 + map = &reserved_mem_table[i]; 2788 + if (!map->size) 2789 + continue; 2790 + 2791 + memset(txtsz, 0, sizeof(txtsz)); 2792 + string_get_size(map->size, 1, STRING_UNITS_2, txtsz, sizeof(txtsz)); 2793 + seq_printf(m, "%s\t\t(%s)\n", map->name, txtsz); 2794 + } 2795 + 2796 + return 0; 2797 + } 2798 + DEFINE_SHOW_ATTRIBUTE(memblock_reserve_mem); 2799 + 2800 + static int __init memblock_init_debugfs(void) 2801 + { 2802 + struct dentry *root; 2803 + 2804 + if (!IS_ENABLED(CONFIG_ARCH_KEEP_MEMBLOCK) && !reserved_mem_count) 2805 + return 0; 2806 + 2807 + root = debugfs_create_dir("memblock", NULL); 2808 + 2809 + if (reserved_mem_count) 2810 + debugfs_create_file("reserve_mem_param", 0444, root, NULL, 2811 + &memblock_reserve_mem_fops); 2812 + 2813 + memblock_debugfs_expose_arrays(root); 2773 2814 return 0; 2774 2815 } 2775 2816 __initcall(memblock_init_debugfs);
+10
tools/testing/memblock/linux/string_helpers.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + #ifndef _LINUX_STRING_HELPERS_H_ 3 + #define _LINUX_STRING_HELPERS_H_ 4 + 5 + /* 6 + * Header stub to avoid test build breakage; we don't need to 7 + * actually implement string_get_size() as it's not used in the tests. 8 + */ 9 + 10 + #endif