From 19c91bd8932a2e00f8de76022c780951166be9a0 Mon Sep 17 00:00:00 2001 From: Wei Yang Date: Fri, 12 Jul 2024 03:51:36 +0000 Subject: [PATCH 01/11] memblock tests: include memory_hotplug.h in mmzone.h as kernel dose In kernel code, memory_hotplug.h is included in mmzone.h instead of in init.h. Let's sync with kernel. This is a preparation for move init.h in common include directory. Signed-off-by: Wei Yang CC: Mike Rapoport Link: https://lore.kernel.org/r/20240712035138.24674-1-richard.weiyang@gmail.com Signed-off-by: Mike Rapoport (Microsoft) --- tools/testing/memblock/linux/init.h | 1 - tools/testing/memblock/linux/mmzone.h | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/testing/memblock/linux/init.h b/tools/testing/memblock/linux/init.h index 828e0ee0bc6c..4aeddce53310 100644 --- a/tools/testing/memblock/linux/init.h +++ b/tools/testing/memblock/linux/init.h @@ -4,7 +4,6 @@ #include #include -#include #define __section(section) __attribute__((__section__(section))) diff --git a/tools/testing/memblock/linux/mmzone.h b/tools/testing/memblock/linux/mmzone.h index 71546e15bdd3..bb682659a12d 100644 --- a/tools/testing/memblock/linux/mmzone.h +++ b/tools/testing/memblock/linux/mmzone.h @@ -3,6 +3,7 @@ #define _TOOLS_MMZONE_H #include +#include struct pglist_data *first_online_pgdat(void); struct pglist_data *next_online_pgdat(struct pglist_data *pgdat); From d68c08173b70952cd74bb45075b843f4a637a43b Mon Sep 17 00:00:00 2001 From: Wei Yang Date: Fri, 12 Jul 2024 03:51:37 +0000 Subject: [PATCH 02/11] memblock tests: include export.h in linkage.h as kernel dose In kernel code, linkage.h includes export.h. Let's sync with kernel. This is a preparation for move init.h in common include directory. Signed-off-by: Wei Yang CC: Mike Rapoport Link: https://lore.kernel.org/r/20240712035138.24674-2-richard.weiyang@gmail.com Signed-off-by: Mike Rapoport (Microsoft) --- tools/include/linux/linkage.h | 2 ++ tools/testing/memblock/linux/init.h | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/include/linux/linkage.h b/tools/include/linux/linkage.h index bc763d500262..20dee24d7e1b 100644 --- a/tools/include/linux/linkage.h +++ b/tools/include/linux/linkage.h @@ -1,4 +1,6 @@ #ifndef _TOOLS_INCLUDE_LINUX_LINKAGE_H #define _TOOLS_INCLUDE_LINUX_LINKAGE_H +#include + #endif /* _TOOLS_INCLUDE_LINUX_LINKAGE_H */ diff --git a/tools/testing/memblock/linux/init.h b/tools/testing/memblock/linux/init.h index 4aeddce53310..bd74abc5cba6 100644 --- a/tools/testing/memblock/linux/init.h +++ b/tools/testing/memblock/linux/init.h @@ -3,7 +3,6 @@ #define _LINUX_INIT_H #include -#include #define __section(section) __attribute__((__section__(section))) From e2ae9cf39f8806d2d8f5eb0a22ba511804a804ec Mon Sep 17 00:00:00 2001 From: Wei Yang Date: Fri, 12 Jul 2024 03:51:38 +0000 Subject: [PATCH 03/11] tools/testing: abstract two init.h into common include directory Currently we have two test suits define its own init.h. This is a little redundant. Let's create a init.h in common include directory and merge these two into it. Signed-off-by: Wei Yang CC: Mike Rapoport CC: Liam R. Howlett Link: https://lore.kernel.org/r/20240712035138.24674-3-richard.weiyang@gmail.com Signed-off-by: Mike Rapoport (Microsoft) --- tools/include/linux/compiler.h | 4 ---- tools/{testing/memblock => include}/linux/init.h | 14 +++++++++++--- tools/testing/radix-tree/linux/init.h | 2 -- tools/testing/radix-tree/maple.c | 2 +- 4 files changed, 12 insertions(+), 10 deletions(-) rename tools/{testing/memblock => include}/linux/init.h (81%) delete mode 100644 tools/testing/radix-tree/linux/init.h diff --git a/tools/include/linux/compiler.h b/tools/include/linux/compiler.h index 6f7f22ac9da5..4b5a45919ff8 100644 --- a/tools/include/linux/compiler.h +++ b/tools/include/linux/compiler.h @@ -126,10 +126,6 @@ # define unlikely(x) __builtin_expect(!!(x), 0) #endif -#ifndef __init -# define __init -#endif - #include /* diff --git a/tools/testing/memblock/linux/init.h b/tools/include/linux/init.h similarity index 81% rename from tools/testing/memblock/linux/init.h rename to tools/include/linux/init.h index bd74abc5cba6..7ed407976dda 100644 --- a/tools/testing/memblock/linux/init.h +++ b/tools/include/linux/init.h @@ -1,9 +1,17 @@ /* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _LINUX_INIT_H -#define _LINUX_INIT_H +#ifndef _TOOLS_LINUX_INIT_H_ +#define _TOOLS_LINUX_INIT_H_ #include +#ifndef __init +# define __init +#endif + +#ifndef __exit +# define __exit +#endif + #define __section(section) __attribute__((__section__(section))) #define __initconst @@ -29,4 +37,4 @@ struct obs_kernel_param { #define early_param(str, fn) \ __setup_param(str, fn, fn, 1) -#endif +#endif /* _TOOLS_LINUX_INIT_H_ */ diff --git a/tools/testing/radix-tree/linux/init.h b/tools/testing/radix-tree/linux/init.h deleted file mode 100644 index 81563c3dfce7..000000000000 --- a/tools/testing/radix-tree/linux/init.h +++ /dev/null @@ -1,2 +0,0 @@ -#define __init -#define __exit diff --git a/tools/testing/radix-tree/maple.c b/tools/testing/radix-tree/maple.c index cd1cf05503b4..3437292babff 100644 --- a/tools/testing/radix-tree/maple.c +++ b/tools/testing/radix-tree/maple.c @@ -14,7 +14,7 @@ #include "test.h" #include #include -#include "linux/init.h" +#include #define module_init(x) #define module_exit(x) From 39f64e402f659890a99d415eaf63a01f3b80a9a8 Mon Sep 17 00:00:00 2001 From: Wei Yang Date: Tue, 6 Aug 2024 01:03:15 +0000 Subject: [PATCH 04/11] memblock test: fix implicit declaration of function 'virt_to_phys' Commit 94ff46de4a73 ("memblock: Move late alloc warning down to phys alloc") introduce the usage of virt_to_phys(), which is not defined in memblock tests. Define it in mm.h to fix the build error. Signed-off-by: Wei Yang Link: https://lore.kernel.org/r/20240806010319.29194-1-richard.weiyang@gmail.com Signed-off-by: Mike Rapoport (Microsoft) --- tools/include/linux/mm.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tools/include/linux/mm.h b/tools/include/linux/mm.h index cad4f2927983..677c37e4a18c 100644 --- a/tools/include/linux/mm.h +++ b/tools/include/linux/mm.h @@ -25,6 +25,12 @@ static inline void *phys_to_virt(unsigned long address) return __va(address); } +#define virt_to_phys virt_to_phys +static inline phys_addr_t virt_to_phys(volatile void *address) +{ + return (phys_addr_t)address; +} + void reserve_bootmem_region(phys_addr_t start, phys_addr_t end, int nid); static inline void totalram_pages_inc(void) From 9f76c2ade323121f9006f6a529e0795317e16b5c Mon Sep 17 00:00:00 2001 From: Wei Yang Date: Tue, 6 Aug 2024 01:03:16 +0000 Subject: [PATCH 05/11] memblock test: add the definition of __setup() Commit 1e4c64b71c9b ("mm/memblock: Add "reserve_mem" to reserved named memory at boot up") introduce usage of __setup(), which is not defined in memblock test. Define it in init.h to fix the build error. Signed-off-by: Wei Yang Link: https://lore.kernel.org/r/20240806010319.29194-2-richard.weiyang@gmail.com Signed-off-by: Mike Rapoport (Microsoft) --- tools/include/linux/init.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/include/linux/init.h b/tools/include/linux/init.h index 7ed407976dda..51b5cde28639 100644 --- a/tools/include/linux/init.h +++ b/tools/include/linux/init.h @@ -34,6 +34,9 @@ struct obs_kernel_param { __aligned(__alignof__(struct obs_kernel_param)) = \ { __setup_str_##unique_id, fn, early } +#define __setup(str, fn) \ + __setup_param(str, fn, fn, 0) + #define early_param(str, fn) \ __setup_param(str, fn, fn, 1) From a88cde5769d523e4ae6aad61237e4a5f6bd2309a Mon Sep 17 00:00:00 2001 From: Wei Yang Date: Tue, 6 Aug 2024 01:03:17 +0000 Subject: [PATCH 06/11] memblock test: fix implicit declaration of function 'memparse' Commit 1e4c64b71c9b ("mm/memblock: Add "reserve_mem" to reserved named memory at boot up") introduce the usage of memparse(), which is not defined in memblock test. Add the definition and link it to fix the build. Signed-off-by: Wei Yang Link: https://lore.kernel.org/r/20240806010319.29194-3-richard.weiyang@gmail.com Signed-off-by: Mike Rapoport (Microsoft) --- tools/include/linux/string.h | 1 + tools/lib/cmdline.c | 53 +++++++++++++++++++++++++++ tools/testing/memblock/Makefile | 2 +- tools/testing/memblock/linux/kernel.h | 1 + 4 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 tools/lib/cmdline.c diff --git a/tools/include/linux/string.h b/tools/include/linux/string.h index db5c99318c79..fb8eda3019b5 100644 --- a/tools/include/linux/string.h +++ b/tools/include/linux/string.h @@ -47,4 +47,5 @@ extern char * __must_check skip_spaces(const char *); extern char *strim(char *); extern void *memchr_inv(const void *start, int c, size_t bytes); +extern unsigned long long memparse(const char *ptr, char **retptr); #endif /* _TOOLS_LINUX_STRING_H_ */ diff --git a/tools/lib/cmdline.c b/tools/lib/cmdline.c new file mode 100644 index 000000000000..c85f00f43c5e --- /dev/null +++ b/tools/lib/cmdline.c @@ -0,0 +1,53 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * From lib/cmdline.c + */ +#include + +#if __has_attribute(__fallthrough__) +# define fallthrough __attribute__((__fallthrough__)) +#else +# define fallthrough do {} while (0) /* fallthrough */ +#endif + +unsigned long long memparse(const char *ptr, char **retptr) +{ + char *endptr; /* local pointer to end of parsed string */ + + unsigned long long ret = strtoll(ptr, &endptr, 0); + + switch (*endptr) { + case 'E': + case 'e': + ret <<= 10; + fallthrough; + case 'P': + case 'p': + ret <<= 10; + fallthrough; + case 'T': + case 't': + ret <<= 10; + fallthrough; + case 'G': + case 'g': + ret <<= 10; + fallthrough; + case 'M': + case 'm': + ret <<= 10; + fallthrough; + case 'K': + case 'k': + ret <<= 10; + endptr++; + fallthrough; + default: + break; + } + + if (retptr) + *retptr = endptr; + + return ret; +} diff --git a/tools/testing/memblock/Makefile b/tools/testing/memblock/Makefile index 7a1ca694a982..d80982ccdc20 100644 --- a/tools/testing/memblock/Makefile +++ b/tools/testing/memblock/Makefile @@ -8,7 +8,7 @@ LDFLAGS += -fsanitize=address -fsanitize=undefined TARGETS = main TEST_OFILES = tests/alloc_nid_api.o tests/alloc_helpers_api.o tests/alloc_api.o \ tests/basic_api.o tests/common.o tests/alloc_exact_nid_api.o -DEP_OFILES = memblock.o lib/slab.o mmzone.o slab.o +DEP_OFILES = memblock.o lib/slab.o mmzone.o slab.o cmdline.o OFILES = main.o $(DEP_OFILES) $(TEST_OFILES) EXTR_SRC = ../../../mm/memblock.c diff --git a/tools/testing/memblock/linux/kernel.h b/tools/testing/memblock/linux/kernel.h index d2f148bd8902..c16d9cd2d1ae 100644 --- a/tools/testing/memblock/linux/kernel.h +++ b/tools/testing/memblock/linux/kernel.h @@ -8,5 +8,6 @@ #include #include #include +#include #endif From 8ac13bc7c266102f1068faafa5314522b68ebe65 Mon Sep 17 00:00:00 2001 From: Wei Yang Date: Tue, 6 Aug 2024 01:03:18 +0000 Subject: [PATCH 07/11] memblock test: fix implicit declaration of function 'isspace' Commit 1e4c64b71c9b ("mm/memblock: Add "reserve_mem" to reserved named memory at boot up") introduce usage of isspace(). Let's include in kernel.h to fix this. Signed-off-by: Wei Yang Link: https://lore.kernel.org/r/20240806010319.29194-4-richard.weiyang@gmail.com Signed-off-by: Mike Rapoport (Microsoft) --- tools/testing/memblock/linux/kernel.h | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/testing/memblock/linux/kernel.h b/tools/testing/memblock/linux/kernel.h index c16d9cd2d1ae..4d1012d5be6e 100644 --- a/tools/testing/memblock/linux/kernel.h +++ b/tools/testing/memblock/linux/kernel.h @@ -9,5 +9,6 @@ #include #include #include +#include #endif From 9e3d665384fca2a1c56283c7a79a968243ef4614 Mon Sep 17 00:00:00 2001 From: Wei Yang Date: Tue, 6 Aug 2024 01:03:19 +0000 Subject: [PATCH 08/11] memblock test: fix implicit declaration of function 'strscpy' Commit 1e4c64b71c9b ("mm/memblock: Add "reserve_mem" to reserved named memory at boot up") introduce the usage of strscpy, which breaks the memblock test. Let's define it as strcpy in userspace to fix it. Signed-off-by: Wei Yang Link: https://lore.kernel.org/r/20240806010319.29194-5-richard.weiyang@gmail.com Signed-off-by: Mike Rapoport (Microsoft) --- tools/include/linux/string.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/include/linux/string.h b/tools/include/linux/string.h index fb8eda3019b5..41e7fa734922 100644 --- a/tools/include/linux/string.h +++ b/tools/include/linux/string.h @@ -12,6 +12,8 @@ void argv_free(char **argv); int strtobool(const char *s, bool *res); +#define strscpy strcpy + /* * glibc based builds needs the extern while uClibc doesn't. * However uClibc headers also define __GLIBC__ hence the hack below From d0f8a8973f265f6a276f99d091af99edfb2b87de Mon Sep 17 00:00:00 2001 From: Wei Yang Date: Thu, 8 Aug 2024 00:14:13 +0000 Subject: [PATCH 09/11] mm/memblock: introduce a new helper memblock_estimated_nr_free_pages() During bootup, system may need the number of free pages in the whole system to do some calculation before all pages are freed to buddy system. Usually this number is get from totalram_pages(). Since we plan to move the free pages accounting in __free_pages_core(), this value may not represent total free pages at the early stage, especially when CONFIG_DEFERRED_STRUCT_PAGE_INIT is enabled. Instead of using raw memblock api, let's introduce a new helper for user to get the estimated number of free pages from memblock point of view. Signed-off-by: Wei Yang CC: David Hildenbrand Reviewed-by: David Hildenbrand Link: https://lore.kernel.org/r/20240808001415.6298-1-richard.weiyang@gmail.com Signed-off-by: Mike Rapoport (Microsoft) --- include/linux/memblock.h | 1 + mm/memblock.c | 17 +++++++++++++++++ tools/include/linux/pfn.h | 1 + 3 files changed, 19 insertions(+) diff --git a/include/linux/memblock.h b/include/linux/memblock.h index fc4d75c6cec3..673d5cae7c81 100644 --- a/include/linux/memblock.h +++ b/include/linux/memblock.h @@ -467,6 +467,7 @@ static inline __init_memblock bool memblock_bottom_up(void) phys_addr_t memblock_phys_mem_size(void); phys_addr_t memblock_reserved_size(void); +unsigned long memblock_estimated_nr_free_pages(void); phys_addr_t memblock_start_of_DRAM(void); phys_addr_t memblock_end_of_DRAM(void); void memblock_enforce_memory_limit(phys_addr_t memory_limit); diff --git a/mm/memblock.c b/mm/memblock.c index 3b9dc2d89b8a..213057603b65 100644 --- a/mm/memblock.c +++ b/mm/memblock.c @@ -1731,6 +1731,23 @@ phys_addr_t __init_memblock memblock_reserved_size(void) return memblock.reserved.total_size; } +/** + * memblock_estimated_nr_free_pages - return estimated number of free pages + * from memblock point of view + * + * During bootup, subsystems might need a rough estimate of the number of free + * pages in the whole system, before precise numbers are available from the + * buddy. Especially with CONFIG_DEFERRED_STRUCT_PAGE_INIT, the numbers + * obtained from the buddy might be very imprecise during bootup. + * + * Return: + * An estimated number of free pages from memblock point of view. + */ +unsigned long __init memblock_estimated_nr_free_pages(void) +{ + return PHYS_PFN(memblock_phys_mem_size() - memblock_reserved_size()); +} + /* lowest address */ phys_addr_t __init_memblock memblock_start_of_DRAM(void) { diff --git a/tools/include/linux/pfn.h b/tools/include/linux/pfn.h index 7512a58189eb..f77a30d70152 100644 --- a/tools/include/linux/pfn.h +++ b/tools/include/linux/pfn.h @@ -7,4 +7,5 @@ #define PFN_UP(x) (((x) + PAGE_SIZE - 1) >> PAGE_SHIFT) #define PFN_DOWN(x) ((x) >> PAGE_SHIFT) #define PFN_PHYS(x) ((phys_addr_t)(x) << PAGE_SHIFT) +#define PHYS_PFN(x) ((unsigned long)((x) >> PAGE_SHIFT)) #endif From 0910bf0ef85c5404aac94394cb31e076e4eb03f1 Mon Sep 17 00:00:00 2001 From: Wei Yang Date: Thu, 8 Aug 2024 00:14:14 +0000 Subject: [PATCH 10/11] kernel/fork.c: get estimated free pages by memblock api Instead of getting estimated free pages from memblock directly, we have introduced an API, memblock_estimated_nr_free_pages(), which is more friendly for users. Just replace it with new API, no functional change. Signed-off-by: Wei Yang CC: Mike Rapoport CC: David Hildenbrand CC: Oleg Nesterov Acked-by: David Hildenbrand Link: https://lore.kernel.org/r/20240808001415.6298-2-richard.weiyang@gmail.com Signed-off-by: Mike Rapoport (Microsoft) --- kernel/fork.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/fork.c b/kernel/fork.c index cc760491f201..d99f148d818b 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -997,7 +997,7 @@ void __init __weak arch_task_cache_init(void) { } static void __init set_max_threads(unsigned int max_threads_suggested) { u64 threads; - unsigned long nr_pages = PHYS_PFN(memblock_phys_mem_size() - memblock_reserved_size()); + unsigned long nr_pages = memblock_estimated_nr_free_pages(); /* * The number of threads shall be limited such that the thread From cb088e38aab4c7e9ce711c18c66e851c8f4227bb Mon Sep 17 00:00:00 2001 From: Wei Yang Date: Thu, 8 Aug 2024 00:14:15 +0000 Subject: [PATCH 11/11] s390/mm: get estimated free pages by memblock api Instead of getting estimated free pages from memblock directly, we have introduced an API, memblock_estimated_nr_free_pages(), which is more friendly for users. Just replace it with new API, no functional change. Signed-off-by: Wei Yang CC: Mike Rapoport CC: David Hildenbrand Acked-by: David Hildenbrand Link: https://lore.kernel.org/r/20240808001415.6298-3-richard.weiyang@gmail.com Signed-off-by: Mike Rapoport (Microsoft) --- arch/s390/mm/init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c index e3d258f9e726..651344206294 100644 --- a/arch/s390/mm/init.c +++ b/arch/s390/mm/init.c @@ -62,7 +62,7 @@ EXPORT_SYMBOL(zero_page_mask); static void __init setup_zero_pages(void) { - unsigned long total_pages = PHYS_PFN(memblock_phys_mem_size() - memblock_reserved_size()); + unsigned long total_pages = memblock_estimated_nr_free_pages(); unsigned int order; struct page *page; int i;