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.

mm/mm_init.c: not always search next deferred_init_pfn from very beginning

In function deferred_init_memmap(), we call
deferred_init_mem_pfn_range_in_zone() to get the next deferred_init_pfn.
But we always search it from the very beginning.

Since we save the index in i, we can leverage this to search from i next
time.

[rppt refine the comment]

Signed-off-by: Wei Yang <richard.weiyang@gmail.com>
Link: https://lore.kernel.org/all/20240605071339.15330-1-richard.weiyang@gmail.com
Signed-off-by: Mike Rapoport (IBM) <rppt@kernel.org>

authored by

Wei Yang and committed by
Mike Rapoport (IBM)
f1180fd2 544b8e14

+14 -28
-19
include/linux/memblock.h
··· 299 299 void __next_mem_pfn_range_in_zone(u64 *idx, struct zone *zone, 300 300 unsigned long *out_spfn, 301 301 unsigned long *out_epfn); 302 - /** 303 - * for_each_free_mem_pfn_range_in_zone - iterate through zone specific free 304 - * memblock areas 305 - * @i: u64 used as loop variable 306 - * @zone: zone in which all of the memory blocks reside 307 - * @p_start: ptr to phys_addr_t for start address of the range, can be %NULL 308 - * @p_end: ptr to phys_addr_t for end address of the range, can be %NULL 309 - * 310 - * Walks over free (memory && !reserved) areas of memblock in a specific 311 - * zone. Available once memblock and an empty zone is initialized. The main 312 - * assumption is that the zone start, end, and pgdat have been associated. 313 - * This way we can use the zone to determine NUMA node, and if a given part 314 - * of the memblock is valid for the zone. 315 - */ 316 - #define for_each_free_mem_pfn_range_in_zone(i, zone, p_start, p_end) \ 317 - for (i = 0, \ 318 - __next_mem_pfn_range_in_zone(&i, zone, p_start, p_end); \ 319 - i != U64_MAX; \ 320 - __next_mem_pfn_range_in_zone(&i, zone, p_start, p_end)) 321 302 322 303 /** 323 304 * for_each_free_mem_pfn_range_in_zone_from - iterate through zone specific
+14 -9
mm/mm_init.c
··· 2021 2021 } 2022 2022 2023 2023 /* 2024 - * This function is meant to pre-load the iterator for the zone init. 2025 - * Specifically it walks through the ranges until we are caught up to the 2026 - * first_init_pfn value and exits there. If we never encounter the value we 2027 - * return false indicating there are no valid ranges left. 2024 + * This function is meant to pre-load the iterator for the zone init from 2025 + * a given point. 2026 + * Specifically it walks through the ranges starting with initial index 2027 + * passed to it until we are caught up to the first_init_pfn value and 2028 + * exits there. If we never encounter the value we return false indicating 2029 + * there are no valid ranges left. 2028 2030 */ 2029 2031 static bool __init 2030 2032 deferred_init_mem_pfn_range_in_zone(u64 *i, struct zone *zone, 2031 2033 unsigned long *spfn, unsigned long *epfn, 2032 2034 unsigned long first_init_pfn) 2033 2035 { 2034 - u64 j; 2036 + u64 j = *i; 2037 + 2038 + if (j == 0) 2039 + __next_mem_pfn_range_in_zone(&j, zone, spfn, epfn); 2035 2040 2036 2041 /* 2037 2042 * Start out by walking through the ranges in this zone that have 2038 2043 * already been initialized. We don't need to do anything with them 2039 2044 * so we just need to flush them out of the system. 2040 2045 */ 2041 - for_each_free_mem_pfn_range_in_zone(j, zone, spfn, epfn) { 2046 + for_each_free_mem_pfn_range_in_zone_from(j, zone, spfn, epfn) { 2042 2047 if (*epfn <= first_init_pfn) 2043 2048 continue; 2044 2049 if (*spfn < first_init_pfn) ··· 2115 2110 { 2116 2111 unsigned long spfn, epfn; 2117 2112 struct zone *zone = arg; 2118 - u64 i; 2113 + u64 i = 0; 2119 2114 2120 2115 deferred_init_mem_pfn_range_in_zone(&i, zone, &spfn, &epfn, start_pfn); 2121 2116 ··· 2146 2141 unsigned long start = jiffies; 2147 2142 struct zone *zone; 2148 2143 int max_threads; 2149 - u64 i; 2144 + u64 i = 0; 2150 2145 2151 2146 /* Bind memory initialisation thread to a local node if possible */ 2152 2147 if (!cpumask_empty(cpumask)) ··· 2221 2216 unsigned long first_deferred_pfn = pgdat->first_deferred_pfn; 2222 2217 unsigned long spfn, epfn, flags; 2223 2218 unsigned long nr_pages = 0; 2224 - u64 i; 2219 + u64 i = 0; 2225 2220 2226 2221 /* Only the last zone may have deferred pages */ 2227 2222 if (zone_end_pfn(zone) != pgdat_end_pfn(pgdat))