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: deferred_init_memmap: use a job per zone

deferred_init_memmap() loops over free memory ranges and creates a
padata_mt_job for every free range that intersects with the zone being
initialized.

padata_do_multithreaded() then splits every such range to several chunks
and runs a thread that initializes struct pages in that chunk using
deferred_init_memmap_chunk(). The number of threads is limited by amount of
the CPUs on the node (or 1 for memoryless nodes).

Looping through free memory ranges is then repeated in
deferred_init_memmap_chunk() first to find the first range that should be
initialized and then to traverse the ranges until the end of the chunk is
reached.

Remove the loop over free memory regions in deferred_init_memmap() and pass
the entire zone to padata_do_multithreaded() so that it will be divided to
several chunks by the parallelization code.

Reviewed-by: David Hildenbrand <david@redhat.com>
Reviewed-by: Wei Yang <richard.weiyang@gmail.com>
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>

+14 -20
+14 -20
mm/mm_init.c
··· 2179 2179 { 2180 2180 pg_data_t *pgdat = data; 2181 2181 const struct cpumask *cpumask = cpumask_of_node(pgdat->node_id); 2182 - unsigned long spfn = 0, epfn = 0; 2183 - unsigned long first_init_pfn, flags; 2182 + int max_threads = deferred_page_init_max_threads(cpumask); 2183 + unsigned long first_init_pfn, last_pfn, flags; 2184 2184 unsigned long start = jiffies; 2185 2185 struct zone *zone; 2186 - int max_threads; 2187 - u64 i = 0; 2188 2186 2189 2187 /* Bind memory initialisation thread to a local node if possible */ 2190 2188 if (!cpumask_empty(cpumask)) ··· 2210 2212 2211 2213 /* Only the highest zone is deferred */ 2212 2214 zone = pgdat->node_zones + pgdat->nr_zones - 1; 2215 + last_pfn = SECTION_ALIGN_UP(zone_end_pfn(zone)); 2213 2216 2214 - max_threads = deferred_page_init_max_threads(cpumask); 2217 + struct padata_mt_job job = { 2218 + .thread_fn = deferred_init_memmap_job, 2219 + .fn_arg = zone, 2220 + .start = first_init_pfn, 2221 + .size = last_pfn - first_init_pfn, 2222 + .align = PAGES_PER_SECTION, 2223 + .min_chunk = PAGES_PER_SECTION, 2224 + .max_threads = max_threads, 2225 + .numa_aware = false, 2226 + }; 2215 2227 2216 - while (deferred_init_mem_pfn_range_in_zone(&i, zone, &spfn, &epfn, first_init_pfn)) { 2217 - first_init_pfn = ALIGN(epfn, PAGES_PER_SECTION); 2218 - struct padata_mt_job job = { 2219 - .thread_fn = deferred_init_memmap_job, 2220 - .fn_arg = zone, 2221 - .start = spfn, 2222 - .size = first_init_pfn - spfn, 2223 - .align = PAGES_PER_SECTION, 2224 - .min_chunk = PAGES_PER_SECTION, 2225 - .max_threads = max_threads, 2226 - .numa_aware = false, 2227 - }; 2228 - 2229 - padata_do_multithreaded(&job); 2230 - } 2228 + padata_do_multithreaded(&job); 2231 2229 2232 2230 /* Sanity check that the next zone really is unpopulated */ 2233 2231 WARN_ON(pgdat->nr_zones < MAX_NR_ZONES && populated_zone(++zone));